From 386b7d3366f1359a265da207a9cafa3edf553b64 Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Mon, 7 Oct 2019 19:13:39 -0400 Subject: Reorganize and commit all the modified TACLeBench code and run scripts --- all_pairs/Makefile | 57 + all_pairs/run_all_pairs.sh | 77 + all_pairs/source/adpcm_dec/ChangeLog.txt | 32 + all_pairs/source/adpcm_dec/adpcm_dec.c | 719 ++ all_pairs/source/adpcm_dec/timedTest.txt | 100 + all_pairs/source/adpcm_enc/ChangeLog.txt | 34 + all_pairs/source/adpcm_enc/adpcm_enc.c | 758 ++ all_pairs/source/ammunition/ChangeLog.txt | 66 + all_pairs/source/ammunition/README | 86 + all_pairs/source/ammunition/ammunition.c | 1185 ++ all_pairs/source/ammunition/ammunitionTimed.txt | 100 + all_pairs/source/ammunition/ammunition_libc.c | 166 + all_pairs/source/ammunition/ammunition_limits.h | 35 + all_pairs/source/ammunition/ammunition_stdio.h | 8 + all_pairs/source/ammunition/ammunition_stdlib.h | 6 + all_pairs/source/ammunition/ammunition_string.h | 18 + all_pairs/source/ammunition/arithm.c | 1384 ++ all_pairs/source/ammunition/arithm.h | 123 + all_pairs/source/ammunition/bits.c | 313 + all_pairs/source/ammunition/bits.h | 60 + all_pairs/source/ammunition/gmon.out | Bin 0 -> 31048 bytes all_pairs/source/ammunition/timeScript | 8 + all_pairs/source/anagram/ChangeLog.txt | 125 + all_pairs/source/anagram/anagram.c | 670 + all_pairs/source/anagram/anagramTest.txt | 100 + all_pairs/source/anagram/anagram_compare.h | 27 + all_pairs/source/anagram/anagram_ctype.h | 45 + all_pairs/source/anagram/anagram_input.c | 2317 ++++ all_pairs/source/anagram/anagram_stdlib.c | 153 + all_pairs/source/anagram/anagram_stdlib.h | 29 + all_pairs/source/anagram/anagram_strings.h | 27 + all_pairs/source/audiobeam/README | 86 + all_pairs/source/audiobeam/audiobeam.c | 594 + all_pairs/source/audiobeam/audiobeam.h | 50 + all_pairs/source/audiobeam/audiobeaminput.c | 5784 +++++++++ all_pairs/source/audiobeam/audiobeamlibm.c | 423 + all_pairs/source/audiobeam/audiobeamlibm.h | 59 + all_pairs/source/audiobeam/audiobeamlibmalloc.c | 14 + all_pairs/source/audiobeam/audiobeamlibmalloc.h | 27 + all_pairs/source/audiobeam/audiobeamlibmath.h | 69 + all_pairs/source/audiobeam/changeLog.txt | 36 + all_pairs/source/audiobeam/license.txt | 21 + all_pairs/source/cjpeg_transupp/ChangeLog.txt | 36 + all_pairs/source/cjpeg_transupp/README | 417 + all_pairs/source/cjpeg_transupp/cjpeg_transupp.c | 718 ++ all_pairs/source/cjpeg_transupp/jpeglib.h | 757 ++ all_pairs/source/cjpeg_wrbmp/ChangeLog.txt | 104 + all_pairs/source/cjpeg_wrbmp/README | 383 + all_pairs/source/cjpeg_wrbmp/cderror.h | 140 + all_pairs/source/cjpeg_wrbmp/cdjpeg.h | 105 + all_pairs/source/cjpeg_wrbmp/cjpeg_wrbmp.c | 225 + all_pairs/source/cjpeg_wrbmp/input.c | 79 + all_pairs/source/cjpeg_wrbmp/jconfig.h | 65 + all_pairs/source/cjpeg_wrbmp/jerror.h | 203 + all_pairs/source/cjpeg_wrbmp/jmorecfg.h | 95 + all_pairs/source/cjpeg_wrbmp/jpeglib.h | 869 ++ all_pairs/source/cleanupSemaphores.c | 10 + all_pairs/source/dijkstra/ChangeLog.txt | 44 + all_pairs/source/dijkstra/dijkstra.c | 204 + all_pairs/source/dijkstra/input.c | 105 + all_pairs/source/dijkstra/input.h | 8 + all_pairs/source/empty.c | 11 + all_pairs/source/epic/ChangeLog.txt | 56 + all_pairs/source/epic/epic.c | 1141 ++ all_pairs/source/epic/epic.h | 72 + all_pairs/source/extra.h | 197 + all_pairs/source/fmref/Changelog.txt | 5 + all_pairs/source/fmref/fmref.c | 283 + all_pairs/source/fmref/license.txt | 21 + all_pairs/source/fmref/math_private.h | 178 + all_pairs/source/fmref/wcclibm.c | 522 + all_pairs/source/fmref/wcclibm.h | 54 + all_pairs/source/g723_enc/ChangeLog.txt | 34 + all_pairs/source/g723_enc/g723_enc.c | 887 ++ all_pairs/source/g723_enc/license.txt | 23 + all_pairs/source/gsm_dec/COPYRIGHT | 16 + all_pairs/source/gsm_dec/ChangeLog.txt | 87 + all_pairs/source/gsm_dec/add.h | 55 + all_pairs/source/gsm_dec/data.h | 865 ++ all_pairs/source/gsm_dec/gsm.h | 14 + all_pairs/source/gsm_dec/gsm_dec.c | 764 ++ all_pairs/source/gsm_dec/private.h | 44 + all_pairs/source/gsm_enc/COPYRIGHT | 16 + all_pairs/source/gsm_enc/ChangeLog.txt | 8 + all_pairs/source/gsm_enc/data.h | 452 + all_pairs/source/gsm_enc/gsm_enc.c | 2072 +++ all_pairs/source/gsm_enc/private.h | 56 + all_pairs/source/h264_dec/changeLog.txt | 41 + all_pairs/source/h264_dec/copyright.txt | 32 + all_pairs/source/h264_dec/h264_dec.c | 610 + all_pairs/source/h264_dec/h264_dec.h | 29 + all_pairs/source/h264_dec/h264_decinput.c | 801 ++ all_pairs/source/huff_dec/ChangeLog.txt | 20 + all_pairs/source/huff_dec/compress.txt | 1107 ++ all_pairs/source/huff_dec/huff_dec.c | 393 + all_pairs/source/huff_enc/ChangeLog.txt | 27 + all_pairs/source/huff_enc/compress.txt | 1107 ++ all_pairs/source/huff_enc/huff_enc.c | 589 + all_pairs/source/mpeg2/ChangeLog.txt | 35 + all_pairs/source/mpeg2/mpeg2.c | 13218 ++++++++++++++++++++ all_pairs/source/ndes/ChangeLog.txt | 20 + all_pairs/source/ndes/ndes.c | 378 + all_pairs/source/petrinet/ChangeLog.txt | 63 + all_pairs/source/petrinet/petrinet.c | 990 ++ all_pairs/source/rijndael_dec/ChangeLog.txt | 58 + all_pairs/source/rijndael_dec/aes.c | 406 + all_pairs/source/rijndael_dec/aes.h | 165 + all_pairs/source/rijndael_dec/aestab.h | 379 + all_pairs/source/rijndael_dec/input_small_enc.c | 2051 +++ all_pairs/source/rijndael_dec/rijndael_dec.c | 195 + all_pairs/source/rijndael_dec/rijndael_dec_libc.c | 66 + all_pairs/source/rijndael_dec/rijndael_dec_libc.h | 24 + all_pairs/source/rijndael_enc/ChangeLog.txt | 98 + all_pairs/source/rijndael_enc/aes.c | 406 + all_pairs/source/rijndael_enc/aes.h | 165 + all_pairs/source/rijndael_enc/aestab.h | 261 + all_pairs/source/rijndael_enc/input_small.c | 1963 +++ all_pairs/source/rijndael_enc/rijndael_enc.c | 238 + all_pairs/source/rijndael_enc/rijndael_enc_libc.c | 66 + all_pairs/source/rijndael_enc/rijndael_enc_libc.h | 24 + all_pairs/source/statemate/ChangeLog.txt | 60 + all_pairs/source/statemate/statemate.c | 1286 ++ all_pairs/source/susan/ChangeLog.txt | 11 + all_pairs/source/susan/LICENSE | 14 + all_pairs/source/susan/input.c | 7292 +++++++++++ all_pairs/source/susan/math_private.h | 178 + all_pairs/source/susan/susan.c | 2014 +++ all_pairs/source/susan/wccfile.c | 79 + all_pairs/source/susan/wccfile.h | 24 + all_pairs/source/susan/wcclibm.c | 444 + all_pairs/source/susan/wcclibm.h | 53 + all_pairs/source/susan/wccmalloc.c | 51 + all_pairs/source/susan/wccmalloc.h | 10 + all_pairs/tacleNames.txt | 19 + baseline/Makefile | 55 + baseline/run_baseline.sh | 65 + baseline/source/adpcm_dec/ChangeLog.txt | 32 + baseline/source/adpcm_dec/adpcm_dec.c | 719 ++ baseline/source/adpcm_dec/timedTest.txt | 100 + baseline/source/adpcm_enc/ChangeLog.txt | 34 + baseline/source/adpcm_enc/adpcm_enc.c | 758 ++ baseline/source/ammunition/ChangeLog.txt | 66 + baseline/source/ammunition/README | 86 + baseline/source/ammunition/ammunition.c | 1185 ++ baseline/source/ammunition/ammunitionTimed.txt | 100 + baseline/source/ammunition/ammunition_libc.c | 166 + baseline/source/ammunition/ammunition_limits.h | 35 + baseline/source/ammunition/ammunition_stdio.h | 8 + baseline/source/ammunition/ammunition_stdlib.h | 6 + baseline/source/ammunition/ammunition_string.h | 18 + baseline/source/ammunition/arithm.c | 1384 ++ baseline/source/ammunition/arithm.h | 123 + baseline/source/ammunition/bits.c | 313 + baseline/source/ammunition/bits.h | 60 + baseline/source/ammunition/gmon.out | Bin 0 -> 31048 bytes baseline/source/ammunition/timeScript | 8 + baseline/source/anagram/ChangeLog.txt | 125 + baseline/source/anagram/anagram.c | 670 + baseline/source/anagram/anagramTest.txt | 100 + baseline/source/anagram/anagram_compare.h | 27 + baseline/source/anagram/anagram_ctype.h | 45 + baseline/source/anagram/anagram_input.c | 2317 ++++ baseline/source/anagram/anagram_stdlib.c | 153 + baseline/source/anagram/anagram_stdlib.h | 29 + baseline/source/anagram/anagram_strings.h | 27 + baseline/source/audiobeam/README | 86 + baseline/source/audiobeam/audiobeam.c | 594 + baseline/source/audiobeam/audiobeam.h | 50 + baseline/source/audiobeam/audiobeaminput.c | 5784 +++++++++ baseline/source/audiobeam/audiobeamlibm.c | 423 + baseline/source/audiobeam/audiobeamlibm.h | 59 + baseline/source/audiobeam/audiobeamlibmalloc.c | 14 + baseline/source/audiobeam/audiobeamlibmalloc.h | 27 + baseline/source/audiobeam/audiobeamlibmath.h | 69 + baseline/source/audiobeam/changeLog.txt | 36 + baseline/source/audiobeam/license.txt | 21 + baseline/source/cjpeg_transupp/ChangeLog.txt | 36 + baseline/source/cjpeg_transupp/README | 417 + baseline/source/cjpeg_transupp/cjpeg_transupp.c | 718 ++ baseline/source/cjpeg_transupp/jpeglib.h | 757 ++ baseline/source/cjpeg_wrbmp/ChangeLog.txt | 104 + baseline/source/cjpeg_wrbmp/README | 383 + baseline/source/cjpeg_wrbmp/cderror.h | 140 + baseline/source/cjpeg_wrbmp/cdjpeg.h | 105 + baseline/source/cjpeg_wrbmp/cjpeg_wrbmp.c | 225 + baseline/source/cjpeg_wrbmp/input.c | 79 + baseline/source/cjpeg_wrbmp/jconfig.h | 65 + baseline/source/cjpeg_wrbmp/jerror.h | 203 + baseline/source/cjpeg_wrbmp/jmorecfg.h | 95 + baseline/source/cjpeg_wrbmp/jpeglib.h | 869 ++ baseline/source/dijkstra/ChangeLog.txt | 44 + baseline/source/dijkstra/dijkstra.c | 204 + baseline/source/dijkstra/input.c | 105 + baseline/source/dijkstra/input.h | 8 + baseline/source/epic/ChangeLog.txt | 56 + baseline/source/epic/epic.c | 1141 ++ baseline/source/epic/epic.h | 72 + baseline/source/extra.h | 116 + baseline/source/fmref/Changelog.txt | 5 + baseline/source/fmref/fmref.c | 283 + baseline/source/fmref/license.txt | 21 + baseline/source/fmref/math_private.h | 178 + baseline/source/fmref/wcclibm.c | 522 + baseline/source/fmref/wcclibm.h | 54 + baseline/source/g723_enc/ChangeLog.txt | 34 + baseline/source/g723_enc/g723_enc.c | 887 ++ baseline/source/g723_enc/license.txt | 23 + baseline/source/gsm_dec/COPYRIGHT | 16 + baseline/source/gsm_dec/ChangeLog.txt | 87 + baseline/source/gsm_dec/add.h | 55 + baseline/source/gsm_dec/data.h | 865 ++ baseline/source/gsm_dec/gsm.h | 14 + baseline/source/gsm_dec/gsm_dec.c | 764 ++ baseline/source/gsm_dec/private.h | 44 + baseline/source/gsm_enc/COPYRIGHT | 16 + baseline/source/gsm_enc/ChangeLog.txt | 8 + baseline/source/gsm_enc/data.h | 452 + baseline/source/gsm_enc/gsm_enc.c | 2072 +++ baseline/source/gsm_enc/private.h | 56 + baseline/source/h264_dec/changeLog.txt | 41 + baseline/source/h264_dec/copyright.txt | 32 + baseline/source/h264_dec/h264_dec.c | 610 + baseline/source/h264_dec/h264_dec.h | 29 + baseline/source/h264_dec/h264_decinput.c | 801 ++ baseline/source/huff_dec/ChangeLog.txt | 20 + baseline/source/huff_dec/compress.txt | 1107 ++ baseline/source/huff_dec/huff_dec.c | 393 + baseline/source/huff_enc/ChangeLog.txt | 27 + baseline/source/huff_enc/compress.txt | 1107 ++ baseline/source/huff_enc/huff_enc.c | 589 + baseline/source/litmusStuff.h | 80 + baseline/source/mpeg2/ChangeLog.txt | 35 + baseline/source/mpeg2/mpeg2.c | 13218 ++++++++++++++++++++ baseline/source/ndes/ChangeLog.txt | 20 + baseline/source/ndes/ndes.c | 378 + baseline/source/petrinet/ChangeLog.txt | 63 + baseline/source/petrinet/petrinet.c | 990 ++ baseline/source/rijndael_dec/ChangeLog.txt | 58 + baseline/source/rijndael_dec/aes.c | 406 + baseline/source/rijndael_dec/aes.h | 165 + baseline/source/rijndael_dec/aestab.h | 379 + baseline/source/rijndael_dec/input_small_enc.c | 2051 +++ baseline/source/rijndael_dec/rijndael_dec.c | 195 + baseline/source/rijndael_dec/rijndael_dec_libc.c | 66 + baseline/source/rijndael_dec/rijndael_dec_libc.h | 24 + baseline/source/rijndael_enc/ChangeLog.txt | 98 + baseline/source/rijndael_enc/aes.c | 406 + baseline/source/rijndael_enc/aes.h | 165 + baseline/source/rijndael_enc/aestab.h | 261 + baseline/source/rijndael_enc/input_small.c | 1963 +++ baseline/source/rijndael_enc/rijndael_enc.c | 238 + baseline/source/rijndael_enc/rijndael_enc_libc.c | 66 + baseline/source/rijndael_enc/rijndael_enc_libc.h | 24 + baseline/source/statemate/ChangeLog.txt | 60 + baseline/source/statemate/statemate.c | 1286 ++ baseline/source/susan/ChangeLog.txt | 11 + baseline/source/susan/LICENSE | 14 + baseline/source/susan/input.c | 7292 +++++++++++ baseline/source/susan/math_private.h | 178 + baseline/source/susan/susan.c | 2014 +++ baseline/source/susan/wccfile.c | 79 + baseline/source/susan/wccfile.h | 24 + baseline/source/susan/wcclibm.c | 444 + baseline/source/susan/wcclibm.h | 53 + baseline/source/susan/wccmalloc.c | 51 + baseline/source/susan/wccmalloc.h | 10 + baseline/tacleNames.txt | 19 + rtss19/extra.h | 194 - run_everything.sh | 21 + 269 files changed, 132087 insertions(+), 194 deletions(-) create mode 100644 all_pairs/Makefile create mode 100755 all_pairs/run_all_pairs.sh create mode 100644 all_pairs/source/adpcm_dec/ChangeLog.txt create mode 100644 all_pairs/source/adpcm_dec/adpcm_dec.c create mode 100644 all_pairs/source/adpcm_dec/timedTest.txt create mode 100644 all_pairs/source/adpcm_enc/ChangeLog.txt create mode 100644 all_pairs/source/adpcm_enc/adpcm_enc.c create mode 100644 all_pairs/source/ammunition/ChangeLog.txt create mode 100644 all_pairs/source/ammunition/README create mode 100644 all_pairs/source/ammunition/ammunition.c create mode 100644 all_pairs/source/ammunition/ammunitionTimed.txt create mode 100644 all_pairs/source/ammunition/ammunition_libc.c create mode 100644 all_pairs/source/ammunition/ammunition_limits.h create mode 100644 all_pairs/source/ammunition/ammunition_stdio.h create mode 100644 all_pairs/source/ammunition/ammunition_stdlib.h create mode 100644 all_pairs/source/ammunition/ammunition_string.h create mode 100644 all_pairs/source/ammunition/arithm.c create mode 100644 all_pairs/source/ammunition/arithm.h create mode 100644 all_pairs/source/ammunition/bits.c create mode 100644 all_pairs/source/ammunition/bits.h create mode 100644 all_pairs/source/ammunition/gmon.out create mode 100644 all_pairs/source/ammunition/timeScript create mode 100644 all_pairs/source/anagram/ChangeLog.txt create mode 100644 all_pairs/source/anagram/anagram.c create mode 100644 all_pairs/source/anagram/anagramTest.txt create mode 100644 all_pairs/source/anagram/anagram_compare.h create mode 100644 all_pairs/source/anagram/anagram_ctype.h create mode 100644 all_pairs/source/anagram/anagram_input.c create mode 100644 all_pairs/source/anagram/anagram_stdlib.c create mode 100644 all_pairs/source/anagram/anagram_stdlib.h create mode 100644 all_pairs/source/anagram/anagram_strings.h create mode 100644 all_pairs/source/audiobeam/README create mode 100644 all_pairs/source/audiobeam/audiobeam.c create mode 100644 all_pairs/source/audiobeam/audiobeam.h create mode 100644 all_pairs/source/audiobeam/audiobeaminput.c create mode 100644 all_pairs/source/audiobeam/audiobeamlibm.c create mode 100644 all_pairs/source/audiobeam/audiobeamlibm.h create mode 100644 all_pairs/source/audiobeam/audiobeamlibmalloc.c create mode 100644 all_pairs/source/audiobeam/audiobeamlibmalloc.h create mode 100644 all_pairs/source/audiobeam/audiobeamlibmath.h create mode 100644 all_pairs/source/audiobeam/changeLog.txt create mode 100644 all_pairs/source/audiobeam/license.txt create mode 100644 all_pairs/source/cjpeg_transupp/ChangeLog.txt create mode 100644 all_pairs/source/cjpeg_transupp/README create mode 100644 all_pairs/source/cjpeg_transupp/cjpeg_transupp.c create mode 100644 all_pairs/source/cjpeg_transupp/jpeglib.h create mode 100644 all_pairs/source/cjpeg_wrbmp/ChangeLog.txt create mode 100644 all_pairs/source/cjpeg_wrbmp/README create mode 100644 all_pairs/source/cjpeg_wrbmp/cderror.h create mode 100644 all_pairs/source/cjpeg_wrbmp/cdjpeg.h create mode 100644 all_pairs/source/cjpeg_wrbmp/cjpeg_wrbmp.c create mode 100644 all_pairs/source/cjpeg_wrbmp/input.c create mode 100644 all_pairs/source/cjpeg_wrbmp/jconfig.h create mode 100644 all_pairs/source/cjpeg_wrbmp/jerror.h create mode 100644 all_pairs/source/cjpeg_wrbmp/jmorecfg.h create mode 100644 all_pairs/source/cjpeg_wrbmp/jpeglib.h create mode 100644 all_pairs/source/cleanupSemaphores.c create mode 100644 all_pairs/source/dijkstra/ChangeLog.txt create mode 100644 all_pairs/source/dijkstra/dijkstra.c create mode 100644 all_pairs/source/dijkstra/input.c create mode 100644 all_pairs/source/dijkstra/input.h create mode 100644 all_pairs/source/empty.c create mode 100644 all_pairs/source/epic/ChangeLog.txt create mode 100644 all_pairs/source/epic/epic.c create mode 100644 all_pairs/source/epic/epic.h create mode 100644 all_pairs/source/extra.h create mode 100644 all_pairs/source/fmref/Changelog.txt create mode 100644 all_pairs/source/fmref/fmref.c create mode 100644 all_pairs/source/fmref/license.txt create mode 100644 all_pairs/source/fmref/math_private.h create mode 100644 all_pairs/source/fmref/wcclibm.c create mode 100644 all_pairs/source/fmref/wcclibm.h create mode 100644 all_pairs/source/g723_enc/ChangeLog.txt create mode 100644 all_pairs/source/g723_enc/g723_enc.c create mode 100644 all_pairs/source/g723_enc/license.txt create mode 100644 all_pairs/source/gsm_dec/COPYRIGHT create mode 100644 all_pairs/source/gsm_dec/ChangeLog.txt create mode 100644 all_pairs/source/gsm_dec/add.h create mode 100644 all_pairs/source/gsm_dec/data.h create mode 100644 all_pairs/source/gsm_dec/gsm.h create mode 100644 all_pairs/source/gsm_dec/gsm_dec.c create mode 100644 all_pairs/source/gsm_dec/private.h create mode 100644 all_pairs/source/gsm_enc/COPYRIGHT create mode 100644 all_pairs/source/gsm_enc/ChangeLog.txt create mode 100644 all_pairs/source/gsm_enc/data.h create mode 100644 all_pairs/source/gsm_enc/gsm_enc.c create mode 100644 all_pairs/source/gsm_enc/private.h create mode 100644 all_pairs/source/h264_dec/changeLog.txt create mode 100644 all_pairs/source/h264_dec/copyright.txt create mode 100644 all_pairs/source/h264_dec/h264_dec.c create mode 100644 all_pairs/source/h264_dec/h264_dec.h create mode 100644 all_pairs/source/h264_dec/h264_decinput.c create mode 100644 all_pairs/source/huff_dec/ChangeLog.txt create mode 100644 all_pairs/source/huff_dec/compress.txt create mode 100644 all_pairs/source/huff_dec/huff_dec.c create mode 100644 all_pairs/source/huff_enc/ChangeLog.txt create mode 100644 all_pairs/source/huff_enc/compress.txt create mode 100644 all_pairs/source/huff_enc/huff_enc.c create mode 100644 all_pairs/source/mpeg2/ChangeLog.txt create mode 100644 all_pairs/source/mpeg2/mpeg2.c create mode 100644 all_pairs/source/ndes/ChangeLog.txt create mode 100644 all_pairs/source/ndes/ndes.c create mode 100644 all_pairs/source/petrinet/ChangeLog.txt create mode 100644 all_pairs/source/petrinet/petrinet.c create mode 100644 all_pairs/source/rijndael_dec/ChangeLog.txt create mode 100644 all_pairs/source/rijndael_dec/aes.c create mode 100644 all_pairs/source/rijndael_dec/aes.h create mode 100644 all_pairs/source/rijndael_dec/aestab.h create mode 100644 all_pairs/source/rijndael_dec/input_small_enc.c create mode 100644 all_pairs/source/rijndael_dec/rijndael_dec.c create mode 100644 all_pairs/source/rijndael_dec/rijndael_dec_libc.c create mode 100644 all_pairs/source/rijndael_dec/rijndael_dec_libc.h create mode 100644 all_pairs/source/rijndael_enc/ChangeLog.txt create mode 100644 all_pairs/source/rijndael_enc/aes.c create mode 100644 all_pairs/source/rijndael_enc/aes.h create mode 100644 all_pairs/source/rijndael_enc/aestab.h create mode 100644 all_pairs/source/rijndael_enc/input_small.c create mode 100644 all_pairs/source/rijndael_enc/rijndael_enc.c create mode 100644 all_pairs/source/rijndael_enc/rijndael_enc_libc.c create mode 100644 all_pairs/source/rijndael_enc/rijndael_enc_libc.h create mode 100644 all_pairs/source/statemate/ChangeLog.txt create mode 100644 all_pairs/source/statemate/statemate.c create mode 100644 all_pairs/source/susan/ChangeLog.txt create mode 100644 all_pairs/source/susan/LICENSE create mode 100644 all_pairs/source/susan/input.c create mode 100644 all_pairs/source/susan/math_private.h create mode 100644 all_pairs/source/susan/susan.c create mode 100644 all_pairs/source/susan/wccfile.c create mode 100644 all_pairs/source/susan/wccfile.h create mode 100644 all_pairs/source/susan/wcclibm.c create mode 100644 all_pairs/source/susan/wcclibm.h create mode 100644 all_pairs/source/susan/wccmalloc.c create mode 100644 all_pairs/source/susan/wccmalloc.h create mode 100644 all_pairs/tacleNames.txt create mode 100644 baseline/Makefile create mode 100755 baseline/run_baseline.sh create mode 100644 baseline/source/adpcm_dec/ChangeLog.txt create mode 100644 baseline/source/adpcm_dec/adpcm_dec.c create mode 100644 baseline/source/adpcm_dec/timedTest.txt create mode 100644 baseline/source/adpcm_enc/ChangeLog.txt create mode 100644 baseline/source/adpcm_enc/adpcm_enc.c create mode 100644 baseline/source/ammunition/ChangeLog.txt create mode 100644 baseline/source/ammunition/README create mode 100644 baseline/source/ammunition/ammunition.c create mode 100644 baseline/source/ammunition/ammunitionTimed.txt create mode 100644 baseline/source/ammunition/ammunition_libc.c create mode 100644 baseline/source/ammunition/ammunition_limits.h create mode 100644 baseline/source/ammunition/ammunition_stdio.h create mode 100644 baseline/source/ammunition/ammunition_stdlib.h create mode 100644 baseline/source/ammunition/ammunition_string.h create mode 100644 baseline/source/ammunition/arithm.c create mode 100644 baseline/source/ammunition/arithm.h create mode 100644 baseline/source/ammunition/bits.c create mode 100644 baseline/source/ammunition/bits.h create mode 100644 baseline/source/ammunition/gmon.out create mode 100644 baseline/source/ammunition/timeScript create mode 100644 baseline/source/anagram/ChangeLog.txt create mode 100644 baseline/source/anagram/anagram.c create mode 100644 baseline/source/anagram/anagramTest.txt create mode 100644 baseline/source/anagram/anagram_compare.h create mode 100644 baseline/source/anagram/anagram_ctype.h create mode 100644 baseline/source/anagram/anagram_input.c create mode 100644 baseline/source/anagram/anagram_stdlib.c create mode 100644 baseline/source/anagram/anagram_stdlib.h create mode 100644 baseline/source/anagram/anagram_strings.h create mode 100644 baseline/source/audiobeam/README create mode 100644 baseline/source/audiobeam/audiobeam.c create mode 100644 baseline/source/audiobeam/audiobeam.h create mode 100644 baseline/source/audiobeam/audiobeaminput.c create mode 100644 baseline/source/audiobeam/audiobeamlibm.c create mode 100644 baseline/source/audiobeam/audiobeamlibm.h create mode 100644 baseline/source/audiobeam/audiobeamlibmalloc.c create mode 100644 baseline/source/audiobeam/audiobeamlibmalloc.h create mode 100644 baseline/source/audiobeam/audiobeamlibmath.h create mode 100644 baseline/source/audiobeam/changeLog.txt create mode 100644 baseline/source/audiobeam/license.txt create mode 100644 baseline/source/cjpeg_transupp/ChangeLog.txt create mode 100644 baseline/source/cjpeg_transupp/README create mode 100644 baseline/source/cjpeg_transupp/cjpeg_transupp.c create mode 100644 baseline/source/cjpeg_transupp/jpeglib.h create mode 100644 baseline/source/cjpeg_wrbmp/ChangeLog.txt create mode 100644 baseline/source/cjpeg_wrbmp/README create mode 100644 baseline/source/cjpeg_wrbmp/cderror.h create mode 100644 baseline/source/cjpeg_wrbmp/cdjpeg.h create mode 100644 baseline/source/cjpeg_wrbmp/cjpeg_wrbmp.c create mode 100644 baseline/source/cjpeg_wrbmp/input.c create mode 100644 baseline/source/cjpeg_wrbmp/jconfig.h create mode 100644 baseline/source/cjpeg_wrbmp/jerror.h create mode 100644 baseline/source/cjpeg_wrbmp/jmorecfg.h create mode 100644 baseline/source/cjpeg_wrbmp/jpeglib.h create mode 100644 baseline/source/dijkstra/ChangeLog.txt create mode 100644 baseline/source/dijkstra/dijkstra.c create mode 100644 baseline/source/dijkstra/input.c create mode 100644 baseline/source/dijkstra/input.h create mode 100644 baseline/source/epic/ChangeLog.txt create mode 100644 baseline/source/epic/epic.c create mode 100644 baseline/source/epic/epic.h create mode 100644 baseline/source/extra.h create mode 100644 baseline/source/fmref/Changelog.txt create mode 100644 baseline/source/fmref/fmref.c create mode 100644 baseline/source/fmref/license.txt create mode 100644 baseline/source/fmref/math_private.h create mode 100644 baseline/source/fmref/wcclibm.c create mode 100644 baseline/source/fmref/wcclibm.h create mode 100644 baseline/source/g723_enc/ChangeLog.txt create mode 100644 baseline/source/g723_enc/g723_enc.c create mode 100644 baseline/source/g723_enc/license.txt create mode 100644 baseline/source/gsm_dec/COPYRIGHT create mode 100644 baseline/source/gsm_dec/ChangeLog.txt create mode 100644 baseline/source/gsm_dec/add.h create mode 100644 baseline/source/gsm_dec/data.h create mode 100644 baseline/source/gsm_dec/gsm.h create mode 100644 baseline/source/gsm_dec/gsm_dec.c create mode 100644 baseline/source/gsm_dec/private.h create mode 100644 baseline/source/gsm_enc/COPYRIGHT create mode 100644 baseline/source/gsm_enc/ChangeLog.txt create mode 100644 baseline/source/gsm_enc/data.h create mode 100644 baseline/source/gsm_enc/gsm_enc.c create mode 100644 baseline/source/gsm_enc/private.h create mode 100644 baseline/source/h264_dec/changeLog.txt create mode 100644 baseline/source/h264_dec/copyright.txt create mode 100644 baseline/source/h264_dec/h264_dec.c create mode 100644 baseline/source/h264_dec/h264_dec.h create mode 100644 baseline/source/h264_dec/h264_decinput.c create mode 100644 baseline/source/huff_dec/ChangeLog.txt create mode 100644 baseline/source/huff_dec/compress.txt create mode 100644 baseline/source/huff_dec/huff_dec.c create mode 100644 baseline/source/huff_enc/ChangeLog.txt create mode 100644 baseline/source/huff_enc/compress.txt create mode 100644 baseline/source/huff_enc/huff_enc.c create mode 100644 baseline/source/litmusStuff.h create mode 100644 baseline/source/mpeg2/ChangeLog.txt create mode 100644 baseline/source/mpeg2/mpeg2.c create mode 100644 baseline/source/ndes/ChangeLog.txt create mode 100644 baseline/source/ndes/ndes.c create mode 100644 baseline/source/petrinet/ChangeLog.txt create mode 100644 baseline/source/petrinet/petrinet.c create mode 100644 baseline/source/rijndael_dec/ChangeLog.txt create mode 100644 baseline/source/rijndael_dec/aes.c create mode 100644 baseline/source/rijndael_dec/aes.h create mode 100644 baseline/source/rijndael_dec/aestab.h create mode 100644 baseline/source/rijndael_dec/input_small_enc.c create mode 100644 baseline/source/rijndael_dec/rijndael_dec.c create mode 100644 baseline/source/rijndael_dec/rijndael_dec_libc.c create mode 100644 baseline/source/rijndael_dec/rijndael_dec_libc.h create mode 100644 baseline/source/rijndael_enc/ChangeLog.txt create mode 100644 baseline/source/rijndael_enc/aes.c create mode 100644 baseline/source/rijndael_enc/aes.h create mode 100644 baseline/source/rijndael_enc/aestab.h create mode 100644 baseline/source/rijndael_enc/input_small.c create mode 100644 baseline/source/rijndael_enc/rijndael_enc.c create mode 100644 baseline/source/rijndael_enc/rijndael_enc_libc.c create mode 100644 baseline/source/rijndael_enc/rijndael_enc_libc.h create mode 100644 baseline/source/statemate/ChangeLog.txt create mode 100644 baseline/source/statemate/statemate.c create mode 100644 baseline/source/susan/ChangeLog.txt create mode 100644 baseline/source/susan/LICENSE create mode 100644 baseline/source/susan/input.c create mode 100644 baseline/source/susan/math_private.h create mode 100644 baseline/source/susan/susan.c create mode 100644 baseline/source/susan/wccfile.c create mode 100644 baseline/source/susan/wccfile.h create mode 100644 baseline/source/susan/wcclibm.c create mode 100644 baseline/source/susan/wcclibm.h create mode 100644 baseline/source/susan/wccmalloc.c create mode 100644 baseline/source/susan/wccmalloc.h create mode 100644 baseline/tacleNames.txt delete mode 100644 rtss19/extra.h create mode 100755 run_everything.sh diff --git a/all_pairs/Makefile b/all_pairs/Makefile new file mode 100644 index 0000000..36cf55a --- /dev/null +++ b/all_pairs/Makefile @@ -0,0 +1,57 @@ +CC = gcc +CFLAGS = -pthread -O2 +LDFLAGS = -lrt +all: bin/cjpeg_wrbmp bin/huff_enc bin/gsm_enc bin/dijkstra bin/h264_dec bin/susan bin/adpcm_enc bin/rijndael_dec bin/huff_dec bin/rijndael_enc bin/gsm_dec bin/anagram bin/epic bin/ammunition bin/g723_enc bin/ndes bin/petrinet bin/statemate bin/cjpeg_transupp bin/mpeg2 bin/fmref bin/audiobeam bin/adpcm_dec bin/cleanupSemaphores + +.PHONY: clean +clean: + rm bin/cjpeg_wrbmp bin/huff_enc bin/gsm_enc bin/dijkstra bin/h264_dec bin/susan bin/adpcm_enc bin/rijndael_dec bin/huff_dec bin/rijndael_enc bin/gsm_dec bin/anagram bin/epic bin/ammunition bin/g723_enc bin/ndes bin/petrinet bin/statemate bin/cjpeg_transupp bin/mpeg2 bin/fmref bin/audiobeam bin/adpcm_dec bin/cleanupSemaphores + +bin/cleanupSemaphores: ./source/extra.h ./source/cleanupSemaphores.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/cjpeg_wrbmp: ./source/extra.h ./source/cjpeg_wrbmp/cjpeg_wrbmp.c ./source/cjpeg_wrbmp/input.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/huff_enc: ./source/extra.h ./source/huff_enc/huff_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/gsm_enc: ./source/extra.h ./source/gsm_enc/gsm_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/dijkstra: ./source/extra.h ./source/dijkstra/dijkstra.c ./source/dijkstra/input.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/h264_dec: ./source/extra.h ./source/h264_dec/h264_dec.c ./source/h264_dec/h264_decinput.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/susan: ./source/extra.h ./source/susan/input.c ./source/susan/susan.c ./source/susan/wccfile.c ./source/susan/wcclibm.c ./source/susan/wccmalloc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/adpcm_enc: ./source/extra.h ./source/adpcm_enc/adpcm_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/rijndael_dec: ./source/extra.h ./source/rijndael_dec/aes.c ./source/rijndael_dec/input_small_enc.c ./source/rijndael_dec/rijndael_dec.c ./source/rijndael_dec/rijndael_dec_libc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/huff_dec: ./source/extra.h ./source/huff_dec/huff_dec.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/rijndael_enc: ./source/extra.h ./source/rijndael_enc/aes.c ./source/rijndael_enc/input_small.c ./source/rijndael_enc/rijndael_enc.c ./source/rijndael_enc/rijndael_enc_libc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/gsm_dec: ./source/extra.h ./source/gsm_dec/gsm_dec.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/anagram: ./source/extra.h ./source/anagram/anagram.c ./source/anagram/anagram_input.c ./source/anagram/anagram_stdlib.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/epic: ./source/extra.h ./source/epic/epic.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/ammunition: ./source/extra.h ./source/ammunition/ammunition.c ./source/ammunition/ammunition_libc.c ./source/ammunition/arithm.c ./source/ammunition/bits.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/g723_enc: ./source/extra.h ./source/g723_enc/g723_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/ndes: ./source/extra.h ./source/ndes/ndes.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/petrinet: ./source/extra.h ./source/petrinet/petrinet.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/statemate: ./source/extra.h ./source/statemate/statemate.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/cjpeg_transupp: ./source/extra.h ./source/cjpeg_transupp/cjpeg_transupp.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/mpeg2: ./source/extra.h ./source/mpeg2/mpeg2.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/fmref: ./source/extra.h ./source/fmref/fmref.c ./source/fmref/wcclibm.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/audiobeam: ./source/extra.h ./source/audiobeam/audiobeam.c ./source/audiobeam/audiobeaminput.c ./source/audiobeam/audiobeamlibmalloc.c ./source/audiobeam/audiobeamlibm.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/adpcm_dec: ./source/extra.h ./source/adpcm_dec/adpcm_dec.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) diff --git a/all_pairs/run_all_pairs.sh b/all_pairs/run_all_pairs.sh new file mode 100755 index 0000000..d48f211 --- /dev/null +++ b/all_pairs/run_all_pairs.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +firstCore=$1 +secondCore=$2 +maxJobs=$3 +runID=$4 +tacleNames=tacleNames.txt + +if [ $# -lt 4 ]; then + echo "Usage $0 [TACLe names file]" + exit +fi + +if [ $# -gt 4 ]; then + echo "Using alternate list of TACLe benchmarks from $5" + tacleNames=$5 +fi + +echo "Making sure that binaries are up to date..." +while read i; do + make bin/$i +done < $tacleNames +echo "Done. Disabling real-time throttling..." + +# Turn off rt throttling +echo -1 > /proc/sys/kernel/sched_rt_runtime_us +echo "Done. Redirecting all interrupts to core 0..." + +# Redirect all interrupts to core 0 +i=0 +for IRQ in /proc/irq/* +do + # Skip default_smp_affinity + if [ -d $IRQ ]; then + irqList[$i]=$(cat $IRQ/smp_affinity_list) + echo 0 > $IRQ/smp_affinity_list + fi + i=$(( $i + 1 )) +done +echo "Done. Beginning benchmarks..." + +# Read the names of each benchmark +j=0 +while read i; do + tacleProg[$j]=$i + j=$(( $j + 1 )) +done < $tacleNames + + +num_tests=$(wc -l < $tacleNames) +for (( i = 0; i < $num_tests ; i++ )) +do + for (( j = $i; j < $num_tests ; j++ )) #loop through programs + do + chrt -r 97 taskset -c $firstCore ./bin/${tacleProg[$i]} ${tacleProg[$i]} $maxJobs $firstCore $secondCore ${tacleProg[$j]} $runID"-A" 1 & \ + chrt -r 97 taskset -c $secondCore ./bin/${tacleProg[$j]} ${tacleProg[$j]} $maxJobs $secondCore $firstCore ${tacleProg[$i]} $runID"-B" 2 & + wait + echo ${tacleProg[$i]} ${tacleProg[$j]} + done + echo COMPLETE: ${tacleProg[$i]} +done + +# Remove semaphores from system +# Leaving them won't hurt these tests, but would be messy and is bad practice +# TODO: Do this directly in the benchmarks. They should clean up after themselves +./bin/cleanupSemaphores + +# Put smp_affinty back the way it was +i=0 +for IRQ in /proc/irq/* +do + if [ -d $IRQ ]; then + echo ${irqList[$i]} > $IRQ/smp_affinity_list + fi + i=$(( $i + 1 )) +done + diff --git a/all_pairs/source/adpcm_dec/ChangeLog.txt b/all_pairs/source/adpcm_dec/ChangeLog.txt new file mode 100644 index 0000000..b9c4f96 --- /dev/null +++ b/all_pairs/source/adpcm_dec/ChangeLog.txt @@ -0,0 +1,32 @@ +File: minver.c +Original provenience: SNU-RT Benchmark Suite for Worst Case Timing Analysis + +2016-02-26: + - Added TACLeBench header to line 1 + - Rename global variable a to minver_a + - Rename global variable b to minver_b + - Rename global variable c to minver_c + - Rename global variable aa to minver_aa + - Rename global variable a_i to minver_a_i + - Rename global variable e to minver_e + - Rename global variable det to minver_det + - Renamed function minver to minver_minver + - Renamed function mmul to minver_mmul + - Renamed function fabs to minver_fabs + - Renamed function main to minver_main + - Created new function main, calling minver_init, minver_main and + returning minver_return + - Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions + - Applied code formatting with astyle as in the example + +2016-03-09: + - Removed static keyword for global variables + - Renamed global variables, prepended adpcm_dec + + 2016-05-23: + - Check sum added and checked against the expected value + + 2016-05-25: + - Corrected expected value \ No newline at end of file diff --git a/all_pairs/source/adpcm_dec/adpcm_dec.c b/all_pairs/source/adpcm_dec/adpcm_dec.c new file mode 100644 index 0000000..6811e69 --- /dev/null +++ b/all_pairs/source/adpcm_dec/adpcm_dec.c @@ -0,0 +1,719 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: adpcm_dec + + Author: Sung-Soo Lim + + Function: + CCITT G.722 ADPCM (Adaptive Differential Pulse Code Modulation) + algorithm. + 16khz sample rate data is stored in the array test_data[SIZE]. + Results are stored in the array compressed[SIZE] and result[SIZE]. + Execution time is determined by the constant SIZE (default value + is 2000). + + Source: SNU-RT Benchmark Suite + + Changes: adpcm benchmark was split into decode and encode benchmark + + License: may be used, modified, and re-distributed freely, but + the SNU-RT Benchmark Suite must be acknowledged + +*/ + +/* + This program is derived from the SNU-RT Benchmark Suite for Worst + Case Timing Analysis by Sung-Soo Lim + + Original source: C Algorithms for Real-Time DSP by P. M. Embree +*/ + +/* + Forward declaration of functions +*/ + +#include "../extra.h" + +void adpcm_dec_decode( int ); +int adpcm_dec_filtez( int *bpl, int *dlt ); +void adpcm_dec_upzero( int dlt, int *dlti, int *bli ); +int adpcm_dec_filtep( int rlt1, int al1, int rlt2, int al2 ); + +int adpcm_dec_logscl( int il, int nbl ); +int adpcm_dec_scalel( int nbl, int shift_constant ); +int adpcm_dec_uppol2( int al1, int al2, int plt, int plt1, int plt2 ); +int adpcm_dec_uppol1( int al1, int apl2, int plt, int plt1 ); + +int adpcm_dec_logsch( int ih, int nbh ); +void adpcm_dec_reset(); +int adpcm_dec_fabs( int n ); +int adpcm_dec_cos( int n ); +int adpcm_dec_sin( int n ); + +void adpcm_dec_init(); +int adpcm_dec_return(); +void adpcm_dec_main(); +//int main( void ); + + +/* + Declaration of macros +*/ +/* common sampling rate for sound cards on IBM/PC */ +#define SAMPLE_RATE 11025 +#define PI 3141 +#define SIZE 3 +#define IN_END 4 + +/* + Declaration of global variables +*/ + +int adpcm_dec_test_data[SIZE * 2], adpcm_dec_result[SIZE * 2]; + +/* Input data for the decoder usually generated by the encoder. */ +int adpcm_dec_compressed[SIZE] = { 0, 253, 32 }; + +/* G722 C code */ + +/* QMF filter coefficients: + scaled by a factor of 4 compared to G722 CCITT recommendation */ +int adpcm_dec_h[24] = { + 12, -44, -44, 212, 48, -624, 128, 1448, + -840, -3220, 3804, 15504, 15504, 3804, -3220, -840, + 1448, 128, -624, 48, 212, -44, -44, 12 +}; + +//int xl,xh; + +/* variables for receive quadrature mirror filter here */ +int adpcm_dec_accumc[11], adpcm_dec_accumd[11]; + +/* outputs of decode() */ +int adpcm_dec_xout1, adpcm_dec_xout2; + +int adpcm_dec_xs, adpcm_dec_xd; + +/* variables for encoder (hi and lo) here */ + +int adpcm_dec_il, adpcm_dec_szl, adpcm_dec_spl, adpcm_dec_sl, adpcm_dec_el; + +int adpcm_dec_qq4_code4_table[16] = { + 0, -20456, -12896, -8968, -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, 4240, 2584, 1200, 0 +}; + + +int adpcm_dec_qq6_code6_table[64] = { + -136, -136, -136, -136, -24808, -21904, -19008, -16704, + -14984, -13512, -12280, -11192, -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, 432, 136, -432, -136 +}; + + +int adpcm_dec_wl_code_table[16] = { + -60, 3042, 1198, 538, 334, 172, 58, -30, + 3042, 1198, 538, 334, 172, 58, -30, -60 +}; + + +int adpcm_dec_ilb_table[32] = { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, + 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834, + 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, + 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008 +}; + +int adpcm_dec_nbl; /* delay line */ +int adpcm_dec_al1, adpcm_dec_al2; +int adpcm_dec_plt, adpcm_dec_plt1, adpcm_dec_plt2; +int adpcm_dec_rs; +int adpcm_dec_dlt; +int adpcm_dec_rlt, adpcm_dec_rlt1, adpcm_dec_rlt2; + + +int adpcm_dec_detl; + + +int adpcm_dec_deth; +int adpcm_dec_sh; /* this comes from adaptive predictor */ +int adpcm_dec_eh; + +int adpcm_dec_qq2_code2_table[4] = { + -7408, -1616, 7408, 1616 +}; + +int adpcm_dec_wh_code_table[4] = { + 798, -214, 798, -214 +}; + + +int adpcm_dec_dh, adpcm_dec_ih; +int adpcm_dec_nbh, adpcm_dec_szh; +int adpcm_dec_sph, adpcm_dec_ph, adpcm_dec_yh, adpcm_dec_rh; + +int adpcm_dec_delay_dhx[6]; + +int adpcm_dec_delay_bph[6]; + +int adpcm_dec_ah1, adpcm_dec_ah2; +int adpcm_dec_ph1, adpcm_dec_ph2; +int adpcm_dec_rh1, adpcm_dec_rh2; + +/* variables for decoder here */ +int adpcm_dec_ilr, adpcm_dec_yl, adpcm_dec_rl; +int adpcm_dec_dec_deth, adpcm_dec_dec_detl, adpcm_dec_dec_dlt; + +int adpcm_dec_dec_del_bpl[6]; + +int adpcm_dec_dec_del_dltx[6]; + +int adpcm_dec_dec_plt, adpcm_dec_dec_plt1, adpcm_dec_dec_plt2; +int adpcm_dec_dec_szl, adpcm_dec_dec_spl, adpcm_dec_dec_sl; +int adpcm_dec_dec_rlt1, adpcm_dec_dec_rlt2, adpcm_dec_dec_rlt; +int adpcm_dec_dec_al1, adpcm_dec_dec_al2; +int adpcm_dec_dl; +int adpcm_dec_dec_nbl, adpcm_dec_dec_yh, adpcm_dec_dec_dh, adpcm_dec_dec_nbh; + +/* variables used in filtez */ +int adpcm_dec_dec_del_bph[6]; + +int adpcm_dec_dec_del_dhx[6]; + +int adpcm_dec_dec_szh; +/* variables used in filtep */ +int adpcm_dec_dec_rh1, adpcm_dec_dec_rh2; +int adpcm_dec_dec_ah1, adpcm_dec_dec_ah2; +int adpcm_dec_dec_ph, adpcm_dec_dec_sph; + +int adpcm_dec_dec_sh, adpcm_dec_dec_rh; + +int adpcm_dec_dec_ph1, adpcm_dec_dec_ph2; + + +/* + Arithmetic math functions +*/ + + +/* MAX: 1 */ +int adpcm_dec_fabs( int n ) +{ + int f; + + + if ( n >= 0 ) + f = n; + else + f = -n; + + return f; +} + + +int adpcm_dec_sin( int rad ) +{ + int diff; + int app = 0; + int inc = 1; + + + /* MAX dependent on rad's value, say 50 */ + _Pragma( "loopbound min 0 max 0" ) + while ( rad > 2 * PI ) + rad -= 2 * PI; + + _Pragma( "loopbound min 0 max 1999" ) + while ( rad < -2 * PI ) + rad += 2 * PI; + + diff = rad; + app = diff; + diff = ( diff * ( -( rad * rad ) ) ) / ( ( 2 * inc ) * ( 2 * inc + 1 ) ); + app = app + diff; + inc++; + + /* REALLY: while(my_fabs(diff) >= 0.00001) { */ + /* MAX: 1000 */ + _Pragma( "loopbound min 849 max 2424" ) + while ( adpcm_dec_fabs( diff ) >= 1 ) { + diff = ( diff * ( -( rad * rad ) ) ) / ( ( 2 * inc ) * ( 2 * inc + 1 ) ); + app = app + diff; + inc++; + } + + return app; +} + + +int adpcm_dec_cos( int rad ) +{ + return ( adpcm_dec_sin( PI / 2 - rad ) ); +} + + +/* + Algorithm core functions +*/ + +/* decode function, result in xout1 and xout2 */ +void adpcm_dec_decode( int input ) +{ + int i; + long int xa1, xa2; /* qmf accumulators */ + int *h_ptr, *ac_ptr, *ac_ptr1, *ad_ptr, *ad_ptr1; + + + /* split transmitted word from input into ilr and ih */ + adpcm_dec_ilr = input & 0x3f; + adpcm_dec_ih = input >> 6; + + /* LOWER SUB_BAND DECODER */ + + /* filtez: compute predictor output for zero section */ + adpcm_dec_dec_szl = adpcm_dec_filtez( adpcm_dec_dec_del_bpl, + adpcm_dec_dec_del_dltx ); + + /* filtep: compute predictor output signal for pole section */ + adpcm_dec_dec_spl = adpcm_dec_filtep( adpcm_dec_dec_rlt1, adpcm_dec_dec_al1, + adpcm_dec_dec_rlt2, adpcm_dec_dec_al2 ); + + adpcm_dec_dec_sl = adpcm_dec_dec_spl + adpcm_dec_dec_szl; + + /* invqxl: compute quantized difference signal for adaptive predic */ + adpcm_dec_dec_dlt = ( ( long )adpcm_dec_dec_detl * + adpcm_dec_qq4_code4_table[adpcm_dec_ilr + >> 2] ) >> 15; + + /* invqxl: compute quantized difference signal for decoder output */ + adpcm_dec_dl = ( ( long )adpcm_dec_dec_detl * + adpcm_dec_qq6_code6_table[adpcm_dec_il] ) >> + 15; + + adpcm_dec_rl = adpcm_dec_dl + adpcm_dec_dec_sl; + + /* logscl: quantizer scale factor adaptation in the lower sub-band */ + adpcm_dec_dec_nbl = adpcm_dec_logscl( adpcm_dec_ilr, adpcm_dec_dec_nbl ); + + /* scalel: computes quantizer scale factor in the lower sub band */ + adpcm_dec_dec_detl = adpcm_dec_scalel( adpcm_dec_dec_nbl, 8 ); + + /* parrec - add pole predictor output to quantized diff. signal */ + /* for partially reconstructed signal */ + adpcm_dec_dec_plt = adpcm_dec_dec_dlt + adpcm_dec_dec_szl; + + /* upzero: update zero section predictor coefficients */ + adpcm_dec_upzero( adpcm_dec_dec_dlt, adpcm_dec_dec_del_dltx, + adpcm_dec_dec_del_bpl ); + + /* uppol2: update second predictor coefficient apl2 and delay it as al2 */ + adpcm_dec_dec_al2 = adpcm_dec_uppol2( adpcm_dec_dec_al1, adpcm_dec_dec_al2, + adpcm_dec_dec_plt, adpcm_dec_dec_plt1, + adpcm_dec_dec_plt2 ); + + /* uppol1: update first predictor coef. (pole setion) */ + adpcm_dec_dec_al1 = adpcm_dec_uppol1( adpcm_dec_dec_al1, adpcm_dec_dec_al2, + adpcm_dec_dec_plt, adpcm_dec_dec_plt1 ); + + /* recons : compute recontructed signal for adaptive predictor */ + adpcm_dec_dec_rlt = adpcm_dec_dec_sl + adpcm_dec_dec_dlt; + + /* done with lower sub band decoder, implement delays for next time */ + adpcm_dec_dec_rlt2 = adpcm_dec_dec_rlt1; + adpcm_dec_dec_rlt1 = adpcm_dec_dec_rlt; + adpcm_dec_dec_plt2 = adpcm_dec_dec_plt1; + adpcm_dec_dec_plt1 = adpcm_dec_dec_plt; + + /* HIGH SUB-BAND DECODER */ + + /* filtez: compute predictor output for zero section */ + adpcm_dec_dec_szh = adpcm_dec_filtez( adpcm_dec_dec_del_bph, + adpcm_dec_dec_del_dhx ); + + /* filtep: compute predictor output signal for pole section */ + adpcm_dec_dec_sph = adpcm_dec_filtep( adpcm_dec_dec_rh1, adpcm_dec_dec_ah1, + adpcm_dec_dec_rh2, adpcm_dec_dec_ah2 ); + + /* predic:compute the predictor output value in the higher sub_band decoder */ + adpcm_dec_dec_sh = adpcm_dec_dec_sph + adpcm_dec_dec_szh; + + /* invqah: in-place compute the quantized difference signal */ + adpcm_dec_dec_dh = ( ( long )adpcm_dec_dec_deth * + adpcm_dec_qq2_code2_table[adpcm_dec_ih] ) >> 15L ; + + /* logsch: update logarithmic quantizer scale factor in hi sub band */ + adpcm_dec_dec_nbh = adpcm_dec_logsch( adpcm_dec_ih, adpcm_dec_dec_nbh ); + + /* scalel: compute the quantizer scale factor in the higher sub band */ + adpcm_dec_dec_deth = adpcm_dec_scalel( adpcm_dec_dec_nbh, 10 ); + + /* parrec: compute partially recontructed signal */ + adpcm_dec_dec_ph = adpcm_dec_dec_dh + adpcm_dec_dec_szh; + + /* upzero: update zero section predictor coefficients */ + adpcm_dec_upzero( adpcm_dec_dec_dh, adpcm_dec_dec_del_dhx, + adpcm_dec_dec_del_bph ); + + /* uppol2: update second predictor coefficient aph2 and delay it as ah2 */ + adpcm_dec_dec_ah2 = adpcm_dec_uppol2( adpcm_dec_dec_ah1, adpcm_dec_dec_ah2, + adpcm_dec_dec_ph, adpcm_dec_dec_ph1, adpcm_dec_dec_ph2 ); + + /* uppol1: update first predictor coef. (pole setion) */ + adpcm_dec_dec_ah1 = adpcm_dec_uppol1( adpcm_dec_dec_ah1, adpcm_dec_dec_ah2, + adpcm_dec_dec_ph, adpcm_dec_dec_ph1 ); + + /* recons : compute recontructed signal for adaptive predictor */ + adpcm_dec_rh = adpcm_dec_dec_sh + adpcm_dec_dec_dh; + + /* done with high band decode, implementing delays for next time here */ + adpcm_dec_dec_rh2 = adpcm_dec_dec_rh1; + adpcm_dec_dec_rh1 = adpcm_dec_rh; + adpcm_dec_dec_ph2 = adpcm_dec_dec_ph1; + adpcm_dec_dec_ph1 = adpcm_dec_dec_ph; + + /* end of higher sub_band decoder */ + + /* end with receive quadrature mirror filters */ + adpcm_dec_xd = adpcm_dec_rl - adpcm_dec_rh; + adpcm_dec_xs = adpcm_dec_rl + adpcm_dec_rh; + + /* receive quadrature mirror filters implemented here */ + h_ptr = adpcm_dec_h; + ac_ptr = adpcm_dec_accumc; + ad_ptr = adpcm_dec_accumd; + xa1 = ( long ) adpcm_dec_xd * ( *h_ptr++ ); + xa2 = ( long ) adpcm_dec_xs * ( *h_ptr++ ); + + /* main multiply accumulate loop for samples and coefficients */ + _Pragma( "loopbound min 10 max 10" ) + for ( i = 0; i < 10; i++ ) { + xa1 += ( long )( *ac_ptr++ ) * ( *h_ptr++ ); + xa2 += ( long )( *ad_ptr++ ) * ( *h_ptr++ ); + } + + /* final mult/accumulate */ + xa1 += ( long )( *ac_ptr ) * ( *h_ptr++ ); + xa2 += ( long )( *ad_ptr ) * ( *h_ptr++ ); + + /* scale by 2^14 */ + adpcm_dec_xout1 = xa1 >> 14; + adpcm_dec_xout2 = xa2 >> 14; + + /* update delay lines */ + ac_ptr1 = ac_ptr - 1; + ad_ptr1 = ad_ptr - 1; + + _Pragma( "loopbound min 10 max 10" ) + for ( i = 0; i < 10; i++ ) { + *ac_ptr-- = *ac_ptr1--; + *ad_ptr-- = *ad_ptr1--; + } + + *ac_ptr = adpcm_dec_xd; + *ad_ptr = adpcm_dec_xs; + + return; +} + + +/* filtez - compute predictor output signal (zero section) */ +/* input: bpl1-6 and dlt1-6, output: szl */ +int adpcm_dec_filtez( int *bpl, int *dlt ) +{ + int i; + long int zl; + + + zl = ( long )( *bpl++ ) * ( *dlt++ ); + + /* MAX: 5 */ + _Pragma( "loopbound min 5 max 5" ) + for ( i = 1; i < 6; i++ ) + zl += ( long )( *bpl++ ) * ( *dlt++ ); + + return ( ( int )( zl >> 14 ) ); /* x2 here */ +} + + +/* filtep - compute predictor output signal (pole section) */ +/* input rlt1-2 and al1-2, output spl */ +int adpcm_dec_filtep( int rlt1, int al1, int rlt2, int al2 ) +{ + long int pl, pl2; + + + pl = 2 * rlt1; + pl = ( long ) al1 * pl; + pl2 = 2 * rlt2; + pl += ( long ) al2 * pl2; + + return ( ( int )( pl >> 15 ) ); +} + + +/* logscl - update log quantizer scale factor in lower sub-band */ +/* note that nbl is passed and returned */ +int adpcm_dec_logscl( int il, int nbl ) +{ + long int wd; + + + wd = ( ( long )nbl * 127L ) >> 7L; /* leak factor 127/128 */ + nbl = ( int )wd + adpcm_dec_wl_code_table[il >> 2]; + + if ( nbl < 0 ) + nbl = 0; + if ( nbl > 18432 ) + nbl = 18432; + + return ( nbl ); +} + + +/* scalel: compute quantizer scale factor in lower or upper sub-band*/ +int adpcm_dec_scalel( int nbl, int shift_constant ) +{ + int wd1, wd2, wd3; + + + wd1 = ( nbl >> 6 ) & 31; + wd2 = nbl >> 11; + wd3 = adpcm_dec_ilb_table[wd1] >> ( shift_constant + 1 - wd2 ); + + return ( wd3 << 3 ); +} + + +/* upzero - inputs: dlt, dlti[0-5], bli[0-5], outputs: updated bli[0-5] */ +/* also implements delay of bli and update of dlti from dlt */ +void adpcm_dec_upzero( int dlt, int *dlti, int *bli ) +{ + int i, wd2, wd3; + + + /*if dlt is zero, then no sum into bli */ + if ( dlt == 0 ) { + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + bli[i] = ( int )( ( 255L * bli[i] ) >> 8L ); /* leak factor of 255/256 */ + } + + } else { + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + if ( ( long )dlt * dlti[i] >= 0 ) + wd2 = 128; + else + wd2 = -128; + + wd3 = ( int )( ( 255L * bli[i] ) >> 8L ); /* leak factor of 255/256 */ + bli[i] = wd2 + wd3; + } + + } + + /* implement delay line for dlt */ + dlti[5] = dlti[4]; + dlti[4] = dlti[3]; + dlti[3] = dlti[2]; + dlti[1] = dlti[0]; + dlti[0] = dlt; + + return; +} + + +/* uppol2 - update second predictor coefficient (pole section) */ +/* inputs: al1, al2, plt, plt1, plt2. outputs: apl2 */ +int adpcm_dec_uppol2( int al1, int al2, int plt, int plt1, int plt2 ) +{ + long int wd2, wd4; + int apl2; + + + wd2 = 4L * ( long )al1; + if ( ( long )plt * plt1 >= 0L ) + wd2 = -wd2; /* check same sign */ + wd2 = wd2 >> 7; /* gain of 1/128 */ + + if ( ( long )plt * plt2 >= 0L ) { + wd4 = wd2 + 128; /* same sign case */ + } else + wd4 = wd2 - 128; + apl2 = wd4 + ( 127L * ( long )al2 >> 7L ); /* leak factor of 127/128 */ + + /* apl2 is limited to +-.75 */ + if ( apl2 > 12288 ) + apl2 = 12288; + if ( apl2 < -12288 ) + apl2 = -12288; + + return ( apl2 ); +} + + +/* uppol1 - update first predictor coefficient (pole section) */ +/* inputs: al1, apl2, plt, plt1. outputs: apl1 */ +int adpcm_dec_uppol1( int al1, int apl2, int plt, int plt1 ) +{ + long int wd2; + int wd3, apl1; + + + wd2 = ( ( long )al1 * 255L ) >> 8L; /* leak factor of 255/256 */ + if ( ( long )plt * plt1 >= 0L ) { + apl1 = ( int )wd2 + 192; /* same sign case */ + } else + apl1 = ( int )wd2 - 192; + + /* note: wd3= .9375-.75 is always positive */ + wd3 = 15360 - apl2; /* limit value */ + if ( apl1 > wd3 ) + apl1 = wd3; + if ( apl1 < -wd3 ) + apl1 = -wd3; + + return ( apl1 ); +} + + +/* logsch - update log quantizer scale factor in higher sub-band */ +/* note that nbh is passed and returned */ +int adpcm_dec_logsch( int ih, int nbh ) +{ + int wd; + + + wd = ( ( long )nbh * 127L ) >> 7L; /* leak factor 127/128 */ + nbh = wd + adpcm_dec_wh_code_table[ih]; + + if ( nbh < 0 ) + nbh = 0; + if ( nbh > 22528 ) + nbh = 22528; + + return ( nbh ); +} + +/* + Initialization- and return-value-related functions +*/ + +/* clear all storage locations */ + +void adpcm_dec_reset() +{ + int i; + + + adpcm_dec_detl = adpcm_dec_dec_detl = 32; /* reset to min scale factor */ + adpcm_dec_deth = adpcm_dec_dec_deth = 8; + adpcm_dec_nbl = adpcm_dec_al1 = adpcm_dec_al2 = adpcm_dec_plt1 = adpcm_dec_plt2 + = adpcm_dec_rlt1 = adpcm_dec_rlt2 = 0; + adpcm_dec_nbh = adpcm_dec_ah1 = adpcm_dec_ah2 = adpcm_dec_ph1 = adpcm_dec_ph2 = + adpcm_dec_rh1 = adpcm_dec_rh2 = 0; + adpcm_dec_dec_nbl = adpcm_dec_dec_al1 = adpcm_dec_dec_al2 = adpcm_dec_dec_plt1 = + adpcm_dec_dec_plt2 = adpcm_dec_dec_rlt1 = adpcm_dec_dec_rlt2 = 0; + adpcm_dec_dec_nbh = adpcm_dec_dec_ah1 = adpcm_dec_dec_ah2 = adpcm_dec_dec_ph1 = + adpcm_dec_dec_ph2 = adpcm_dec_dec_rh1 = adpcm_dec_dec_rh2 = 0; + + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + ////delay_dltx[i] = 0; + adpcm_dec_delay_dhx[i] = 0; + adpcm_dec_dec_del_dltx[i] = 0; + adpcm_dec_dec_del_dhx[i] = 0; + } + + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + //delay_bpl[i] = 0; + adpcm_dec_delay_bph[i] = 0; + adpcm_dec_dec_del_bpl[i] = 0; + adpcm_dec_dec_del_bph[i] = 0; + } + + _Pragma( "loopbound min 11 max 11" ) + for ( i = 0; i < 11; i++ ) { + adpcm_dec_accumc[i] = 0; + adpcm_dec_accumd[i] = 0; + } + + return; +} + +void adpcm_dec_init() +{ + int i, j, f; + volatile int x = 0; + /* read in amplitude and frequency for test data */ + j = 10; + f = 2000; + + /* reset, initialize required memory */ + adpcm_dec_reset(); + + /* 16 KHz sample rate */ + /* XXmain_0, MAX: 2 */ + /* Since the number of times we loop in adpcm_dec_sin depends on the + argument we add the fact: xxmain_0:[]: */ + _Pragma( "loopbound min 3 max 3" ) + for ( i = 0 ; i < SIZE ; i++ ) { + adpcm_dec_test_data[i] = ( int ) j * adpcm_dec_cos( f * PI * i ); + + /* avoid constant-propagation optimizations */ + adpcm_dec_test_data[i] += x; + } +} + +int adpcm_dec_return() +{ + int i; + int check_sum = 0; + + for (i = 0; i < IN_END; i += 2) + { + check_sum += ( adpcm_dec_result[i] + adpcm_dec_result[i + 1] ); + } + + return check_sum != -2; +} + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) adpcm_dec_main( void ) +{ + int i; + + _Pragma( "loopbound min 2 max 2" ) + for ( i = 0 ; i < IN_END ; i += 2 ) { + adpcm_dec_decode( adpcm_dec_compressed[i / 2] ); + adpcm_dec_result[i] = adpcm_dec_xout1; + adpcm_dec_result[i + 1] = adpcm_dec_xout2; + } + +} + + +int main(int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsComplete + + Original name: adpcm_encoder + + Changes: no major functional changes + + License: may be used, modified, and re-distributed freely, but the + SNU-RT Benchmark Suite must be acknowledged + +*/ + + +/* common sampling rate for sound cards on IBM/PC */ + +#include "../extra.h" +#define SAMPLE_RATE 11025 + +#define PI 3141 +#define SIZE 3 +#define IN_END 4 + + +/* + Forward declaration of functions +*/ + +int adpcm_enc_encode( int, int ); +int adpcm_enc_filtez( int *bpl, int *dlt ); +void adpcm_enc_upzero( int dlt, int *dlti, int *bli ); +int adpcm_enc_filtep( int rlt1, int al1, int rlt2, int al2 ); +int adpcm_enc_quantl( int el, int detl ); +int adpcm_enc_logscl( int il, int nbl ); +int adpcm_enc_scalel( int nbl, int shift_constant ); +int adpcm_enc_uppol2( int al1, int al2, int plt, int plt1, int plt2 ); +int adpcm_enc_uppol1( int al1, int apl2, int plt, int plt1 ); +int adpcm_enc_logsch( int ih, int nbh ); +void adpcm_enc_reset(); +int adpcm_enc_fabs( int n ); +int adpcm_enc_cos( int n ); +int adpcm_enc_sin( int n ); +int adpcm_enc_abs( int n ); +void adpcm_enc_init(void); +void adpcm_enc_main(void); +int adpcm_enc_return(void); +//int main(void); + +/* + Forward declaration of global variables +*/ + +int adpcm_enc_test_data[SIZE * 2], adpcm_enc_compressed[SIZE]; + + +/* G722 C code */ + +/* variables for transimit quadrature mirror filter here */ +int adpcm_enc_tqmf[24]; + +/* QMF filter coefficients: +scaled by a factor of 4 compared to G722 CCITT recommendation */ +int adpcm_enc_h[24] = { + 12, -44, -44, 212, 48, -624, 128, 1448, + -840, -3220, 3804, 15504, 15504, 3804, -3220, -840, + 1448, 128, -624, 48, 212, -44, -44, 12 +}; + +int adpcm_enc_xl, adpcm_enc_xh; + +/* variables for encoder (hi and lo) here */ + +int adpcm_enc_il, adpcm_enc_szl, adpcm_enc_spl, adpcm_enc_sl, adpcm_enc_el; + +int adpcm_enc_qq4_code4_table[16] = { + 0, -20456, -12896, -8968, -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, 4240, 2584, 1200, 0 +}; + +int adpcm_enc_qq5_code5_table[32] = { + -280, -280, -23352, -17560, -14120, -11664, -9752, -8184, + -6864, -5712, -4696, -3784, -2960, -2208, -1520, -880, + 23352, 17560, 14120, 11664, 9752, 8184, 6864, 5712, + 4696, 3784, 2960, 2208, 1520, 880, 280, -280 +}; + +int adpcm_enc_qq6_code6_table[64] = { + -136, -136, -136, -136, -24808, -21904, -19008, -16704, +-14984, -13512, -12280, -11192, -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, 432, 136, -432, -136 +}; + +int adpcm_enc_delay_bpl[6]; + +int adpcm_enc_delay_dltx[6]; + +int adpcm_enc_wl_code_table[16] = { + -60, 3042, 1198, 538, 334, 172, 58, -30, + 3042, 1198, 538, 334, 172, 58, -30, -60 +}; + +int adpcm_enc_ilb_table[32] = { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, + 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834, + 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, + 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008 +}; + +int adpcm_enc_nbl; /* delay line */ +int adpcm_enc_al1, adpcm_enc_al2; +int adpcm_enc_plt, adpcm_enc_plt1, adpcm_enc_plt2; +int adpcm_enc_dlt; +int adpcm_enc_rlt, adpcm_enc_rlt1, adpcm_enc_rlt2; + +/* decision levels - pre-multiplied by 8, 0 to indicate end */ +int adpcm_enc_decis_levl[30] = { + 280, 576, 880, 1200, 1520, 1864, 2208, 2584, + 2960, 3376, 3784, 4240, 4696, 5200, 5712, 6288, + 6864, 7520, 8184, 8968, 9752, 10712, 11664, 12896, + 14120, 15840, 17560, 20456, 23352, 32767 +}; + +int adpcm_enc_detl; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +int adpcm_enc_quant26bt_pos[31] = { + 61, 60, 59, 58, 57, 56, 55, 54, + 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 38, + 37, 36, 35, 34, 33, 32, 32 +}; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +int adpcm_enc_quant26bt_neg[31] = { + 63, 62, 31, 30, 29, 28, 27, 26, + 25, 24, 23, 22, 21, 20, 19, 18, + 17, 16, 15, 14, 13, 12, 11, 10, + 9, 8, 7, 6, 5, 4, 4 +}; + + +int adpcm_enc_deth; +int adpcm_enc_sh; /* this comes from adaptive predictor */ +int adpcm_enc_eh; + +int adpcm_enc_qq2_code2_table[4] = { + -7408, -1616, 7408, 1616 +}; + +int adpcm_enc_wh_code_table[4] = { + 798, -214, 798, -214 +}; + + +int adpcm_enc_dh, adpcm_enc_ih; +int adpcm_enc_nbh, adpcm_enc_szh; +int adpcm_enc_sph, adpcm_enc_ph, adpcm_enc_yh; + +int adpcm_enc_delay_dhx[6]; +int adpcm_enc_delay_bph[6]; + +int adpcm_enc_ah1, adpcm_enc_ah2; +int adpcm_enc_ph1, adpcm_enc_ph2; +int adpcm_enc_rh1, adpcm_enc_rh2; + + +/* G722 encode function two ints in, one 8 bit output */ + +/* put input samples in xin1 = first value, xin2 = second value */ +/* returns il and ih stored together */ + + +/* MAX: 1 */ +int adpcm_enc_abs( int n ) +{ + int m; + + + if ( n >= 0 ) + m = n; + else + m = -n; + + return m; +} + + +/* MAX: 1 */ +int adpcm_enc_fabs( int n ) +{ + int f; + + + if ( n >= 0 ) + f = n; + else + f = -n; + + return f; +} + + +int adpcm_enc_sin( int rad ) +{ + int diff; + int app = 0; + int inc = 1; + + + /* MAX dependent on rad's value, say 50 */ + _Pragma("loopbound min 0 max 0") + while ( rad > 2 * PI ) { + rad -= 2 * PI; + } + + /* MAX dependent on rad's value, say 50 */ + _Pragma("loopbound min 0 max 1999") + while ( rad < -2 * PI ) { + rad += 2 * PI; + } + + diff = rad; + app = diff; + diff = (diff * (-(rad*rad))) / ((2 * inc) * (2 * inc + 1)); + app = app + diff; + inc++; + + /* REALLY: while(my_fabs(diff) >= 0.00001) { */ + /* MAX: 1000 */ + _Pragma("loopbound min 849 max 2424") + while ( adpcm_enc_fabs( diff ) >= 1 ) { + diff = (diff * (-(rad*rad))) / ((2 * inc) * (2 * inc + 1)); + app = app + diff; + inc++; + } + + return app; +} + + +int adpcm_enc_cos( int rad ) +{ + return( adpcm_enc_sin( PI / 2 - rad ) ); +} + + +/* MAX: 1 */ +int adpcm_enc_encode( int xin1, int xin2 ) +{ + int i; + int *h_ptr, *tqmf_ptr, *tqmf_ptr1; + long int xa, xb; + int decis; + + + /* transmit quadrature mirror filters implemented here */ + h_ptr = adpcm_enc_h; + tqmf_ptr = adpcm_enc_tqmf; + xa = (long)(*tqmf_ptr++) * (*h_ptr++); + xb = (long)(*tqmf_ptr++) * (*h_ptr++); + + /* main multiply accumulate loop for samples and coefficients */ + /* MAX: 10 */ + _Pragma("loopbound min 10 max 10") + for ( i = 0; i < 10; i++ ) { + xa += (long)(*tqmf_ptr++) * (*h_ptr++); + xb += (long)(*tqmf_ptr++) * (*h_ptr++); + } + + /* final mult/accumulate */ + xa += (long)(*tqmf_ptr++) * (*h_ptr++); + xb += (long)(*tqmf_ptr) * (*h_ptr++); + + /* update delay line tqmf */ + tqmf_ptr1 = tqmf_ptr - 2; + /* MAX: 22 */ + _Pragma("loopbound min 22 max 22") + for ( i = 0; i < 22; i++ ) { + *tqmf_ptr-- = *tqmf_ptr1--; + } + + *tqmf_ptr-- = xin1; + *tqmf_ptr = xin2; + + /* scale outputs */ + adpcm_enc_xl = (xa + xb) >> 15; + adpcm_enc_xh = (xa - xb) >> 15; + + /* end of quadrature mirror filter code */ + + /* starting with lower sub band encoder */ + + /* filtez - compute predictor output section - zero section */ + adpcm_enc_szl = adpcm_enc_filtez( adpcm_enc_delay_bpl, adpcm_enc_delay_dltx ); + + /* filtep - compute predictor output signal (pole section) */ + adpcm_enc_spl = adpcm_enc_filtep( adpcm_enc_rlt1, adpcm_enc_al1, adpcm_enc_rlt2, adpcm_enc_al2 ); + + /* compute the predictor output value in the lower sub_band encoder */ + adpcm_enc_sl = adpcm_enc_szl + adpcm_enc_spl; + adpcm_enc_el = adpcm_enc_xl - adpcm_enc_sl; + + /* quantl: quantize the difference signal */ + adpcm_enc_il = adpcm_enc_quantl( adpcm_enc_el, adpcm_enc_detl ); + + /* invqxl: computes quantized difference signal */ + /* for invqbl, truncate by 2 lsbs, so mode = 3 */ + adpcm_enc_dlt = ( (long) adpcm_enc_detl * adpcm_enc_qq4_code4_table[adpcm_enc_il >> 2] ) >> 15; + + /* logscl: updates logarithmic quant. scale factor in low sub band */ + adpcm_enc_nbl = adpcm_enc_logscl( adpcm_enc_il, adpcm_enc_nbl ); + + /* scalel: compute the quantizer scale factor in the lower sub band */ + /* calling parameters nbl and 8 (constant such that scalel can be scaleh) */ + adpcm_enc_detl = adpcm_enc_scalel( adpcm_enc_nbl, 8 ); + + /* parrec - simple addition to compute recontructed signal for adaptive pred */ + adpcm_enc_plt = adpcm_enc_dlt + adpcm_enc_szl; + + /* upzero: update zero section predictor coefficients (sixth order)*/ + /* calling parameters: dlt, dlt1, dlt2, ..., dlt6 from dlt */ + /* bpli (linear_buffer in which all six values are delayed */ + /* return params: updated bpli, delayed dltx */ + adpcm_enc_upzero( adpcm_enc_dlt, adpcm_enc_delay_dltx, adpcm_enc_delay_bpl ); + + /* uppol2- update second predictor coefficient apl2 and delay it as al2 */ + /* calling parameters: al1, al2, plt, plt1, plt2 */ + adpcm_enc_al2 = adpcm_enc_uppol2( adpcm_enc_al1, adpcm_enc_al2, adpcm_enc_plt, adpcm_enc_plt1, adpcm_enc_plt2 ); + + /* uppol1 :update first predictor coefficient apl1 and delay it as al1 */ + /* calling parameters: al1, apl2, plt, plt1 */ + adpcm_enc_al1 = adpcm_enc_uppol1( adpcm_enc_al1, adpcm_enc_al2, adpcm_enc_plt, adpcm_enc_plt1); + + /* recons : compute recontructed signal for adaptive predictor */ + adpcm_enc_rlt = adpcm_enc_sl + adpcm_enc_dlt; + + /* done with lower sub_band encoder; now implement delays for next time*/ + adpcm_enc_rlt2 = adpcm_enc_rlt1; + adpcm_enc_rlt1 = adpcm_enc_rlt; + adpcm_enc_plt2 = adpcm_enc_plt1; + adpcm_enc_plt1 = adpcm_enc_plt; + + /* high band encode */ + + adpcm_enc_szh = adpcm_enc_filtez( adpcm_enc_delay_bph, adpcm_enc_delay_dhx ); + + adpcm_enc_sph = adpcm_enc_filtep( adpcm_enc_rh1, adpcm_enc_ah1, adpcm_enc_rh2, adpcm_enc_ah2 ); + + /* predic: sh = sph + szh */ + adpcm_enc_sh = adpcm_enc_sph + adpcm_enc_szh; + /* subtra: eh = xh - sh */ + adpcm_enc_eh = adpcm_enc_xh - adpcm_enc_sh; + + /* quanth - quantization of difference signal for higher sub-band */ + /* quanth: in-place for speed params: eh, deth (has init. value) */ + if ( adpcm_enc_eh >= 0 ) + adpcm_enc_ih = 3; /* 2,3 are pos codes */ + else + adpcm_enc_ih = 1; /* 0,1 are neg codes */ + + decis = ( 564L * (long)adpcm_enc_deth ) >> 12L; + if ( adpcm_enc_abs( adpcm_enc_eh ) > decis ) + adpcm_enc_ih--; /* mih = 2 case */ + + /* invqah: compute the quantized difference signal, higher sub-band*/ + adpcm_enc_dh = ( (long)adpcm_enc_deth * adpcm_enc_qq2_code2_table[adpcm_enc_ih] ) >> 15L ; + + /* logsch: update logarithmic quantizer scale factor in hi sub-band*/ + adpcm_enc_nbh = adpcm_enc_logsch( adpcm_enc_ih, adpcm_enc_nbh ); + + /* note : scalel and scaleh use same code, different parameters */ + adpcm_enc_deth = adpcm_enc_scalel( adpcm_enc_nbh, 10 ); + + /* parrec - add pole predictor output to quantized diff. signal */ + adpcm_enc_ph = adpcm_enc_dh + adpcm_enc_szh; + + /* upzero: update zero section predictor coefficients (sixth order) */ + /* calling parameters: dh, dhi, bphi */ + /* return params: updated bphi, delayed dhx */ + adpcm_enc_upzero( adpcm_enc_dh, adpcm_enc_delay_dhx, adpcm_enc_delay_bph ); + + /* uppol2: update second predictor coef aph2 and delay as ah2 */ + /* calling params: ah1, ah2, ph, ph1, ph2 */ + adpcm_enc_ah2 = adpcm_enc_uppol2( adpcm_enc_ah1, adpcm_enc_ah2, adpcm_enc_ph, adpcm_enc_ph1, adpcm_enc_ph2 ); + + /* uppol1: update first predictor coef. aph2 and delay it as ah1 */ + adpcm_enc_ah1 = adpcm_enc_uppol1( adpcm_enc_ah1, adpcm_enc_ah2, adpcm_enc_ph, adpcm_enc_ph1 ); + + /* recons for higher sub-band */ + adpcm_enc_yh = adpcm_enc_sh + adpcm_enc_dh; + + /* done with higher sub-band encoder, now Delay for next time */ + adpcm_enc_rh2 = adpcm_enc_rh1; + adpcm_enc_rh1 = adpcm_enc_yh; + adpcm_enc_ph2 = adpcm_enc_ph1; + adpcm_enc_ph1 = adpcm_enc_ph; + + /* multiplex ih and il to get signals together */ + return( adpcm_enc_il | (adpcm_enc_ih << 6) ); +} + + +/* filtez - compute predictor output signal (zero section) */ +/* input: bpl1-6 and dlt1-6, output: szl */ +int adpcm_enc_filtez( int *bpl, int *dlt ) +{ + int i; + long int zl; + + + zl = (long)(*bpl++) * (*dlt++); + + /* MAX: 5 */ + _Pragma("loopbound min 5 max 5") + for ( i = 1; i < 6; i++ ) { + zl += (long)(*bpl++) * (*dlt++); + } + + return( (int)(zl >> 14) ); /* x2 here */ +} + + +/* filtep - compute predictor output signal (pole section) */ +/* input rlt1-2 and al1-2, output spl */ +int adpcm_enc_filtep( int rlt1, int al1, int rlt2, int al2 ) +{ + long int pl, pl2; + + + pl = 2 * rlt1; + pl = (long) al1 * pl; + pl2 = 2 * rlt2; + pl += (long) al2 * pl2; + + return( (int)(pl >> 15) ); +} + + +/* quantl - quantize the difference signal in the lower sub-band */ +int adpcm_enc_quantl( int el, int detl ) +{ + int ril, mil; + long int wd, decis; + + + /* abs of difference signal */ + wd = adpcm_enc_abs( el ); + + /* determine mil based on decision levels and detl gain */ + /* MAX: 30 */ + _Pragma("loopbound min 1 max 30") + for ( mil = 0; mil < 30; mil++ ) { + decis = (adpcm_enc_decis_levl[mil] * (long)detl) >> 15L; + if ( wd <= decis ) + break; + } + + /* if mil=30 then wd is less than all decision levels */ + if ( el >= 0 ) + ril = adpcm_enc_quant26bt_pos[mil]; + else + ril = adpcm_enc_quant26bt_neg[mil]; + + return( ril ); +} + + +/* invqxl is either invqbl or invqal depending on parameters passed */ +/* returns dlt, code table is pre-multiplied by 8 */ + +/* int invqxl(int il,int detl,int *code_table,int mode) */ +/* { */ +/* long int dlt; */ +/* dlt = (long)detl*code_table[il >> (mode-1)]; */ +/* return((int)(dlt >> 15)); */ +/* } */ + +/* logscl - update log quantizer scale factor in lower sub-band */ +/* note that nbl is passed and returned */ +int adpcm_enc_logscl( int il, int nbl ) +{ + long int wd; + + + wd = ((long)nbl * 127L) >> 7L; /* leak factor 127/128 */ + nbl = (int)wd + adpcm_enc_wl_code_table[il >> 2]; + + if ( nbl < 0 ) + nbl = 0; + if ( nbl > 18432 ) + nbl = 18432; + + return( nbl ); +} + + +/* scalel: compute quantizer scale factor in lower or upper sub-band*/ +int adpcm_enc_scalel( int nbl, int shift_constant ) +{ + int wd1, wd2, wd3; + + + wd1 = (nbl >> 6) & 31; + wd2 = nbl >> 11; + wd3 = adpcm_enc_ilb_table[wd1] >> (shift_constant + 1 - wd2); + + return( wd3 << 3 ); +} + + +/* upzero - inputs: dlt, dlti[0-5], bli[0-5], outputs: updated bli[0-5] */ +/* also implements delay of bli and update of dlti from dlt */ +void adpcm_enc_upzero( int dlt, int *dlti, int *bli ) +{ + int i, wd2, wd3; + + + /*if dlt is zero, then no sum into bli */ + if ( dlt == 0 ) { + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++ ) { + bli[i] = (int)((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + } + + } else { + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++ ) { + if ( (long)dlt * dlti[i] >= 0 ) + wd2 = 128; + else + wd2 = -128; + + wd3 = (int)((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + bli[i] = wd2 + wd3; + } + + } + + /* implement delay line for dlt */ + dlti[5] = dlti[4]; + dlti[4] = dlti[3]; + dlti[3] = dlti[2]; + dlti[1] = dlti[0]; + dlti[0] = dlt; + + return; +} + + +/* uppol2 - update second predictor coefficient (pole section) */ +/* inputs: al1, al2, plt, plt1, plt2. outputs: apl2 */ +int adpcm_enc_uppol2( int al1, int al2, int plt, int plt1, int plt2 ) +{ + long int wd2, wd4; + int apl2; + + + wd2 = 4L * (long)al1; + if ( (long)plt * plt1 >= 0L ) + wd2 = -wd2; /* check same sign */ + wd2 = wd2 >> 7; /* gain of 1/128 */ + + if ( (long)plt * plt2 >= 0L ) { + wd4 = wd2 + 128; /* same sign case */ + } else { + wd4 = wd2 - 128; + } + apl2 = wd4 + (127L*(long)al2 >> 7L); /* leak factor of 127/128 */ + + /* apl2 is limited to +-.75 */ + if ( apl2 > 12288 ) + apl2 = 12288; + if ( apl2 < -12288 ) + apl2 = -12288; + + return( apl2 ); +} + + +/* uppol1 - update first predictor coefficient (pole section) */ +/* inputs: al1, apl2, plt, plt1. outputs: apl1 */ +int adpcm_enc_uppol1( int al1, int apl2, int plt, int plt1 ) +{ + long int wd2; + int wd3, apl1; + + + wd2 = ((long)al1 * 255L) >> 8L; /* leak factor of 255/256 */ + if ( (long)plt * plt1 >= 0L ) { + apl1 = (int)wd2 + 192; /* same sign case */ + } else { + apl1 = (int)wd2 - 192; + } + + /* note: wd3= .9375-.75 is always positive */ + wd3 = 15360 - apl2; /* limit value */ + if ( apl1 > wd3 ) + apl1 = wd3; + if ( apl1 < -wd3 ) + apl1 = -wd3; + + return( apl1 ); +} + + +/* INVQAH: inverse adaptive quantizer for the higher sub-band */ +/* returns dh, code table is pre-multiplied by 8 */ +/* int invqah(int ih,int deth) */ +/* { */ +/* long int rdh; */ +/* rdh = ((long)deth*qq2_code2_table[ih]) >> 15L ; */ +/* return((int)(rdh )); */ +/* } */ + + +/* logsch - update log quantizer scale factor in higher sub-band */ +/* note that nbh is passed and returned */ +int adpcm_enc_logsch( int ih, int nbh ) +{ + int wd; + + + wd = ((long)nbh * 127L) >> 7L; /* leak factor 127/128 */ + nbh = wd + adpcm_enc_wh_code_table[ih]; + + if ( nbh < 0 ) + nbh = 0; + if ( nbh > 22528 ) + nbh = 22528; + + return( nbh ); +} + + +/* + Initialization- and return-value-related functions +*/ + +/* clear all storage locations */ + +void adpcm_enc_reset(void) +{ + int i; + + adpcm_enc_detl = 32; /* reset to min scale factor */ + adpcm_enc_deth = 8; + adpcm_enc_nbl = adpcm_enc_al1 = adpcm_enc_al2 = adpcm_enc_plt1 = adpcm_enc_plt2 = adpcm_enc_rlt1 = adpcm_enc_rlt2 = 0; + adpcm_enc_nbh = adpcm_enc_ah1 = adpcm_enc_ah2 = adpcm_enc_ph1 = adpcm_enc_ph2 = adpcm_enc_rh1 = adpcm_enc_rh2 = 0; + + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++) { + adpcm_enc_delay_dltx[i] = 0; + adpcm_enc_delay_dhx[i] = 0; + } + + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++ ) { + adpcm_enc_delay_bpl[i] = 0; + adpcm_enc_delay_bph[i] = 0; + } + + _Pragma("loopbound min 23 max 23") + for ( i = 0; i < 23; i++ ) { + adpcm_enc_tqmf[i] = 0; + } + + return; +} + + +void adpcm_enc_init(void) +{ + int i, j, f; + volatile int x = 0; + + /* reset, initialize required memory */ + adpcm_enc_reset(); + + /* read in amplitude and frequency for test data */ + j = 10; + f = 2000; + + /* 16 KHz sample rate */ + /* XXmain_0, MAX: 2 */ + /* Since the number of times we loop in my_sin depends on the argument we + add the fact: xxmain_0:[]: */ + _Pragma("loopbound min 3 max 3") + for ( i = 0 ; i < SIZE ; i++) { + adpcm_enc_test_data[i] = (int) j * adpcm_enc_cos( f * PI * i ); + + /* avoid constant-propagation optimizations */ + adpcm_enc_test_data[i] += x; + } +} + + +int adpcm_enc_return(void) +{ + int i; + int check_sum = 0; + + for ( i = 0 ; i < IN_END ; i += 2 ) { + check_sum += adpcm_enc_compressed[i/2]; + } + + return check_sum != 385; +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) adpcm_enc_main(void) +{ + int i; + /* MAX: 2 */ + _Pragma("loopbound min 2 max 2") + for ( i = 0 ; i < IN_END ; i += 2 ) { + adpcm_enc_compressed[i/2] = adpcm_enc_encode( adpcm_enc_test_data[i], adpcm_enc_test_data[i+1] ); + } + +} + +int main(int argc, char **argv) +{ + SET_UP + for(jobsComplete=-1; jobsComplete unsigned char +- Fix compiler warnings "'&&' within '||'": + Place additional parentheses +- Remove usages and comments related to the macros + HAVE_MEMMOVE, NDEBUG, HAVE_MEMCMP +- Remove comment related to unused NO_TEMPLATE macro +2016-05-02: +- Change C++ style comments to ISO C90 compliant comments +- Avoid mixing declarations and code: move declaration of variable writePos in + functions ammunition_sprintf_d and ammunition_sprintf_u +- Change datatype in function ammunition_bits_test of iteration variables i and + j from int to unsigned int to avoid comparison between signed and unsigned + integer expressions +- Add forward declarations to ammunition.c +- Introduce variable ammunition_result +- Parantheses around comparison in functions ammunition_isdigit and + ammunition_isspace +- Remove usage of limits.h, move definitions of limits into separate file + ammunition_limits.h +- Remove unconditional assignments of variable result to zero after each test in + functions ammunition_bits_test and ammunition_arithm_test +- Remove unused functions unsigned_integer_maximum, integer_minimum, + integer_maximum, integer_remainder +- Remove unused declaration of function default_arithmetic_overflow_reaction +- Remove unused variables zero_constant_itself, zero_constant +- Remove unused declarations of functions set_unsigned_integer_overflow_reaction + and set_integer_overflow_reaction +- Remove block #ifndef MAX_INTEGER_OPERAND_SIZE, set definition of + MAX_INTEGER_OPERAND_SIZE to 128, since this is default +2016-05-10: +- Integrate new version of arithm library from ammunition repository from + dino repository on github (commit: db9cfab042c332abb234ec8d72750103010981c1), + which hanles arithmetic shifts by negative numbers. This change now makes all + test cases in ammunition.c pass. Update headers unsigned int bits => int bits +- Remove assert statements +- Fix memcmp implementation: dereferencing pointer was missing +- Add loop-bound annotation to memcmp +- Fix strcmp implementation +- Integrate working versions of memcpy and memset from pm benchmark +- Update signature of ammunition_memcpy to original version: + void *memcpy(void *dest, const void *src, size_x n); +- Move functions from libc into separate file, introduce header files + ammunition_limits.h, ammunition_stdio.h, ammunition_stdlib.h, + ammunition_string.h +- Fix overflow in sprintf_d: change datatype of variable 'copyOfNumber' from int + to long, since the negative value of INT_MIN is undefined + 2016-05-17: +- Remove all static declarations of global functions +- Rename variables 'digit_number' to digit_num to keep lines below 80 characters +- Rename op1_digit_number to op1_digit_number and op1_digit_num in function + 'ammunition_multiply_unsigned_integer_without_overflow_reaction' +- Rename variable 'scaled_op1_digit_number' in function + 'ammunition_divide_unsigned_integer_without_overflow_reaction' +- Apply code formatting with astyle + +2017-08-18: +- Add explicit casts to silence g++ warnings. diff --git a/all_pairs/source/ammunition/README b/all_pairs/source/ammunition/README new file mode 100644 index 0000000..8caddf4 --- /dev/null +++ b/all_pairs/source/ammunition/README @@ -0,0 +1,86 @@ +This directory AMMUNITION contains reusable packages on C/C++: +`allocate', `vlobject', `objstack', `hashtab', `commline', `ticker', +`position', `errors', `bits', `arithm', `IEEE': + o allocate + Allocating and freeing memory with automatic fixing some + allocation errors. + o vlobject + Work with variable length objects (VLO). Any number of bytes + may be added to and removed from the end of VLO. If it is + needed the memory allocated for storing variable length object + may be expanded possibly with changing the object place. But + between any additions of the bytes (or tailoring) the object + place is not changed. To decrease number of changes of the + object place the memory being allocated for the object is + longer than the current object length. + o objstack + Work with stacks of objects (OS). Work with the object on the + stack top is analogous to one with a variable length object. + One motivation for the package is the problem of growing char + strings in symbol tables. Memory for OS is allocated by + segments. A segment may contain more one objects. The most + recently allocated segment contains object on the top of OS. + If there is not sufficient free memory for the top object than + new segment is created and the top object is transferred into + the new segment, i.e. there is not any memory reallocation. + Therefore the top object may change its address. But other + objects never change address. + o hashtab + Work with hash tables. The package permits to work + simultaneously with several expandable hash tables. Besides + insertion and search of elements the elements from the hash + tables can be also removed. The table element can be only a + pointer. The size of hash tables is not fixed. The hash + table will be automatically expanded when its occupancy will + became big. + o position + Work with source code positions. The package serves to + support information about source positions of compiled files + taking all included files into account. + o errors + Output of compiler messages. The package serves output + one-pass or multi-pass compiler messages of various modes + (errors, warnings, fatal, system errors and appended messages) + in Unix style or for traditional listing. The package also + permits adequate error reporting for included files. + o commline + Work with command line. The package implements features + analogous to ones of public domain function `getopt'. The + goal of the package creation is to use more readable language + of command line description and to use command line + description as help output of program. + o ticker + Simultaneous work with several tickers (timers). + o bits + Work with bit strings (copying, moving, setting, testing, + comparison). + o arithm + Implementing host machine-independently arbitrary precision + integer numbers arithmetic. The implementation of the package + functions are not sufficiently efficient in order to use for + run-time. The package functions are oriented to implement + constant-folding in compilers, cross-compilers. + o IEEE + Implementing host machine-independently IEEE floating point + arithmetic. The implementation of the package functions are + not sufficiently efficient in order to use for run-time. The + package functions are oriented to implement constant-folding + in compilers, cross-compilers. + + There are files with corresponding names and extensions `.h' +(interface file for C/C++), `.c' (implementation file on C), and +`.cpp' (implementation file on C++). + + To install AMMUNITION see file INSTALL in the current directory. + + There are also shell scripts for testing the package with +corresponding names and extension `.tst'. Documentation of the +reusable packages is in files `ammunition.txt', `ammunition.dvi', +`ammunition.ps', `ammunition.info*', `ammunition*.html', +`ammunition*.rtf' for C and `ammunition++.txt', `ammunition++.dvi', +`ammunition++.ps', `ammunition++.info*', `ammunition++*.html', +`ammunition++*.rtf'. + +Please send bug reports and comments to vmakarov@fnmail.com + +Vladimir Makarov diff --git a/all_pairs/source/ammunition/ammunition.c b/all_pairs/source/ammunition/ammunition.c new file mode 100644 index 0000000..224babd --- /dev/null +++ b/all_pairs/source/ammunition/ammunition.c @@ -0,0 +1,1185 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: ammunition + + Author: Vladimir Makarov + + Function: Tests reusable packages bits and arith + bits: Work with bit strings (copying, moving, setting, testing, comparison). + arith: Implementing host machine-independently arbitrary precision integer + numbers arithmetic. The implementation of the package functions are not + sufficiently efficient in order to use for run-time. The package + functions are oriented to implement constant-folding in compilers, + cross-compilers. + + Source: DINO programming language repository + https://github.com/dino-lang/dino/ + + Changes: no major functional changes + + License: GPL 2 and LGPL 2 + +*/ + +#include "../extra.h" +#include "bits.h" +#include "arithm.h" +#include "ammunition_stdlib.h" +#include "ammunition_stdio.h" +#include "ammunition_string.h" + +/* + Forward declaration of functions +*/ + +void ammunition_reset_str_bits( char *str, char *s ); +void ammunition_reset_str_arithm( char *str, char *s, char *d, char *e, + char *g ); +int ammunition_bits_test(); +int ammunition_arithm_test(); +void ammunition_init( void ); +int ammunition_return( void ); +void ammunition_main( void ); +//int main( void ); + + +/* + Forward declaration of global variables +*/ + +int ammunition_result; + + +/* + Core functions +*/ + +void ammunition_reset_str_bits( char *str, char *s ) +{ + int i; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < 8; i++ ) { + str[i] = 0; + s[i] = 0; + } +} + + +void ammunition_reset_str_arithm( char *str, char *s, char *d, char *e, + char *g ) +{ + int i; + _Pragma( "loopbound min 20 max 20" ) + for ( i = 0; i < 20; i++ ) { + str[i] = 0; + s[i] = 0; + } + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < 4; i++ ) { + d[i] = 0; + e[i] = 0; + } + + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) + g[i] = 0; +} + + +int ammunition_bits_test() +{ + char str[8]; + char str1[8]; + + int result = 0; + unsigned int i, j; + + /* Test 1 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) { + if ( BIT ( str, i ) ) + result = 1; + } + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) { + SET_BIT ( str, i, 1 ); + _Pragma( "loopbound min 64 max 64" ) + for ( j = 0; j < sizeof ( str ) * CHAR_BIT; j++ ) + if ( j <= i ) { + if ( BIT ( str, j ) == 0 ) + result = 1; + } else + if ( BIT ( str, j ) ) + result = 1; + } + + /* Test 2 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) + if ( !ammunition_is_zero_bit_string ( + str, i, ( sizeof ( str ) * CHAR_BIT - i ) / 2 + 1 ) ) + result = 1; + ammunition_bit_string_set ( str, 13, 1, 35 ); + _Pragma( "loopbound min 13 max 13" ) + for ( i = 0; i < 13; i++ ) + if ( !ammunition_is_zero_bit_string ( str, i, 13 - i ) ) + result = 1; + _Pragma( "loopbound min 35 max 35" ) + for ( i = 13; i < 48; i++ ) + if ( ammunition_is_zero_bit_string ( str, i, 48 - i ) ) + result = 1; + _Pragma( "loopbound min 16 max 16" ) + for ( i = 48; i < sizeof ( str ) * CHAR_BIT; i++ ) + if ( !ammunition_is_zero_bit_string ( str, i, + sizeof ( str ) * CHAR_BIT - i ) ) + result = 1; + + /* Test 3 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 42 max 42" ) + for ( i = 0; i + i / 2 + 1 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, i, 1, i / 2 + 1 ); + if ( !ammunition_is_zero_bit_string ( str, 0, i - 1 ) ) + result = 1; + if ( ammunition_is_zero_bit_string ( str, i, i / 2 + 1 ) ) + result = 1; + if ( !ammunition_is_zero_bit_string ( + str, i + i / 2 + 1, sizeof ( str ) * CHAR_BIT - ( i + i / 2 + 1 ) ) ) + result = 1; + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + } + + /* Test 4 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 40 ); + _Pragma( "loopbound min 42 max 42" ) + for ( i = 0; i < 42; i++ ) + if ( ammunition_bit_string_comparison ( str, i, str1, i, 42 - i ) != 0 ) + result = 1; + _Pragma( "loopbound min 43 max 43" ) + for ( i = 0; i < 43; i++ ) + if ( ammunition_bit_string_comparison ( str, i, str1, i, + sizeof ( str ) * CHAR_BIT - i ) + <= 0 ) + result = 1; + _Pragma( "loopbound min 43 max 43" ) + for ( i = 0; i < 43; i++ ) + if ( ammunition_bit_string_comparison ( str1, i, str, i, + sizeof ( str ) * CHAR_BIT - i ) + >= 0 ) + result = 1; + + /* Test 5 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_copy ( str1, i + 5, str, i, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str1, i + 5, str, i, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + /* Test 6 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_move ( str, i + 5, str, i, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str, i + 5, str1, i, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + /* Test 7 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_move ( str, i, str, i + 5, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str, i, str1, i + 5, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + return result; +} + + +int ammunition_arithm_test() +{ + int result = 0; + + /* Test 1 */ + int i; + char str [20], s[20], d[4], e[4], g[6]; + + ammunition_integer_from_string ( 4, "-2147483649", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "2147483648", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + } + + /* Test 2 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "4294967296", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + } + + /* Test 3 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MAX ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "1", e ); + ammunition_add_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX - 4 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 4 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_add_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, INT_MAX ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, i + 1 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_add_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i + 1 ) + result = 1; + } + + /* Test 4 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_unsigned_integer_from_string ( 4, "1", e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX - 4 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 4 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + ammunition_sprintf_u( str, UINT_MAX ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i + 1 ) + result = 1; + } + + /* Test 5 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MIN ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "1", e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN + 4 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 4 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, INT_MIN ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 10 - i ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i - 10 ) + result = 1; + } + + /* Test 6 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX - 2 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, UINT_MAX - 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_subtract_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_subtract_unsigned_integer ( 4, d, d, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_subtract_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i - i / 2 ) + result = 1; + } + + /* Test 7 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MAX / 2 + 1 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "2", e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN / 2 - 1 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "2", e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX / 3 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 3 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, ( INT_MAX / 3 ) * 3 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + ammunition_sprintf_d( str, INT_MIN / 2 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 2 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, ( INT_MIN / 2 ) * 2 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, i + 1000 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i * ( i + 1000 ) ) + result = 1; + } + + /* Test 8 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX / 5 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 5 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + ammunition_sprintf_u( str, ( UINT_MAX / 2 ) * 2 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i * ( i / 2 ) ) + result = 1; + } + + /* Test 9 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "10", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_divide_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_divide_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i / ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ) + result = 1; + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_divide_integer ( 4, d, e, e ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_atoi ( s ) != i / ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ) + result = 1; + } + + /* Test 10 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_divide_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 20 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_divide_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i / ( i / 20 + 1 ) ) + result = 1; + } + + /* Test 11 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_remainder ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 20 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_unsigned_integer_remainder ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i % ( i / 20 + 1 ) ) + result = 1; + } + + /* Test 12 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 0, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 32, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 8, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "5" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_left ( 4, d, -13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + + /* Test 13 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 32, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "5" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_right ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_left ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 32, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-6" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_right ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-17" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_left ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-17" ) != 0 ) + result = 1; + + /* Test 14 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 0, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 22, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 8, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "345088" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_right ( 4, d, -13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + + /* Test 15 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 21, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "345088" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_left ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_right ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 21, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-345088" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_left ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_right ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1105018880" ) != 0 ) + result = 1; + + /* Test 16 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_eq_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_eq_integer ( 4, d, e ) ) + result = 1; + + /* Test 17 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_eq_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_eq_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 18 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ne_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_ne_integer ( 4, d, e ) ) + result = 1; + + /* Test 19 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ne_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_ne_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 20 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_gt_integer ( 4, d, e ) ) + result = 1; + + /* Test 21 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 22 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_integer ( 4, d, e ) ) + result = 1; + + /* Test 23 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 24 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_integer ( 4, d, e ) ) + result = 1; + + /* Test 25 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 26 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_le_integer ( 4, d, e ) ) + result = 1; + + /* Test 27 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 28 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "70000", d ); + ammunition_change_unsigned_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "30000", d ); + ammunition_change_unsigned_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "30000" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "11230000", g ); + ammunition_change_unsigned_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "11230000" ) != 0 ) + result = 1; + + /* Test 29 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "40000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "-33000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "30000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "30000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-30000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-30000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "11230000", g ); + ammunition_change_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "11230000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-11230000", g ); + ammunition_change_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-11230000" ) != 0 ) + result = 1; + + /* Test 30 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "4294967295", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "4294967295" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "96", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1380" ) != 0 ) + result = 1; + + /* Test 31 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "1348", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "-1", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "96", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1380" ) != 0 ) + result = 1; + + /* Test 32 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "4294967295", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "96", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "64" ) != 0 ) + result = 1; + + /* Test 33 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "1348", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "-1", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "96", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "64" ) != 0 ) + result = 1; + + /* Test 34 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "4294965947" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "0", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "4294967295" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "4294967295", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + + /* Test 35 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "-1349" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "0", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + + return result; +} + + +/* + Initialization- and return-value-related functions +*/ + +void ammunition_init( void ) +{ + ammunition_result = 0; +} + +int ammunition_return( void ) +{ + return ammunition_result; +} + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) ammunition_main( void ) +{ + ammunition_result |= ammunition_bits_test(); + ammunition_result |= ammunition_arithm_test(); +} + + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= '0' ) & ( c <= '9' ) ) + return 1; + else + return 0; +} + +int ammunition_isspace( int c ) +{ + return ( c == ' ' ) | ( c == '\t' ) | ( c == '\n' ) | ( c == '\r' ); +} + +void *ammunition_memcpy( void *dest, const void *src, size_x size ) +{ + size_x i; + _Pragma( "loopbound min 2 max 6" ) + for ( i = 0; i < size; i++ ) + ( ( unsigned char * )dest )[i] = ( ( unsigned char * )src )[i]; + + return dest; +} + + +void *ammunition_memset( void *s, int c, size_x n ) +{ + size_x i; + _Pragma( "loopbound min 0 max 4" ) + for ( i = 0; i < n; i++ ) + ( ( unsigned char * )s )[i] = ( unsigned char )c; + + return s; +} + + +int ammunition_memcmp ( const void *mem1, const void *mem2, size_x size ) +{ + const unsigned char *p1 = (const unsigned char *) mem1, + *p2 = (const unsigned char *) mem2; + _Pragma( "loopbound min 0 max 4" ) + while ( size-- ) + if ( *p1 != *p2 ) + return ( *p1 - *p2 ); + else + p1++, p2++; + return 0; +} + + +/* The following function is an analog of standard C function + `memmove'. The function returns the first operand. */ + +void *ammunition_memmove ( void *s1, const void *s2, size_x n ) +{ + int i; + + if ( ( ( char * ) s1 < ( char * ) s2 && ( char * ) s1 + n <= ( char * ) s2 ) + || ( ( char * ) s2 < ( char * ) s1 + && ( char * ) s2 + n <= ( char * ) s1 ) ) + return ( void * ) ammunition_memcpy ( s1, s2, n ); + if ( ( char * ) s1 < ( char * ) s2 && ( char * ) s1 + n > ( char * ) s2 ) { + _Pragma( "loopbound min 0 max 4" ) + for ( i = 0; ( size_x ) i < n; i++ ) + ( ( char * ) s1 ) [i] = ( ( char * ) s2 ) [i]; + } else { + _Pragma( "loopbound min 0 max 4" ) + for ( i = n - 1; i >= 0; i-- ) + ( ( char * ) s1 )[i] = ( ( char * ) s2 ) [i]; + } + return s1; +} + +int ammunition_strcmp ( const char *str1, const char *str2 ) +{ + _Pragma( "loopbound min 1 max 4008" ) + while ( *str1 && ( *str1 == *str2 ) ) + str1++, str2++; + return *( const unsigned char * )str1 - *( const unsigned char * )str2; +} + +int ammunition_atoi ( const char *str ) +{ + int result = 0; + int sign = ( str[0] == '-' ? -1 : 1 ); + + int readingPos = 0; + if ( str[0] == '-' || str[0] == '+' ) + readingPos++; + _Pragma( "loopbound min 1 max 1" ) + do { + result *= 10; + result += str[readingPos++] - 48; + } while ( str[readingPos] != 0 ); + + return sign * result; +} + + +int ammunition_sprintf_d( char *s, int number ) +{ + /* How many decimal digits do we need? */ + char digits = 0; + unsigned char writePos = 0; + long long copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + digits++; + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + writePos = digits; + if ( number < 0 ) { + writePos++; + s[0] = '-'; + } + s[writePos] = 0; + + copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + s[--writePos] = 48 + ( ( copyOfNumber >= 0 ? + copyOfNumber : -copyOfNumber ) % 10 ); + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + return digits + ( number < 0 ? 1 : 0 ); +} + + +int ammunition_sprintf_u( char *s, unsigned int number ) +{ + /* How many decimal digits do we need? */ + char digits = 0; + unsigned char writePos = 0; + unsigned long copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + digits++; + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + writePos = digits; + s[writePos] = 0; + + copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + s[--writePos] = 48 + ( copyOfNumber % 10 ); + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + return digits; +} diff --git a/all_pairs/source/ammunition/ammunition_limits.h b/all_pairs/source/ammunition/ammunition_limits.h new file mode 100644 index 0000000..0de4c82 --- /dev/null +++ b/all_pairs/source/ammunition/ammunition_limits.h @@ -0,0 +1,35 @@ +#ifndef AMMUNITION_LIMITS_H +#define AMMUNITION_LIMITS_H + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif +#ifndef UCHAR_MAX +#define UCHAR_MAX 255 +#endif +#ifndef SCHAR_MAX +#define SCHAR_MAX 127 +#endif +#ifndef SCHAR_MIN +#define SCHAR_MIN (-128) +#endif +#ifndef USHRT_MAX +#define USHRT_MAX 65535 +#endif +#ifndef SHRT_MAX +#define SHRT_MAX 32767 +#endif +#ifndef SHRT_MIN +#define SHRT_MIN (-32768) +#endif +#ifndef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1) +#endif +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif +#ifndef INT_MIN +#define INT_MIN (-INT_MAX-1) +#endif + +#endif /* #ifndef AMMUNITION_LIMITS_H */ diff --git a/all_pairs/source/ammunition/ammunition_stdio.h b/all_pairs/source/ammunition/ammunition_stdio.h new file mode 100644 index 0000000..a3a7a4b --- /dev/null +++ b/all_pairs/source/ammunition/ammunition_stdio.h @@ -0,0 +1,8 @@ +#ifndef AMMUNITION_STDIO_H +#define AMMUNITION_STDIO_H + +int ammunition_sprintf_d( char *s, int number ); + +int ammunition_sprintf_u( char *s, unsigned int number ); + +#endif diff --git a/all_pairs/source/ammunition/ammunition_stdlib.h b/all_pairs/source/ammunition/ammunition_stdlib.h new file mode 100644 index 0000000..d907212 --- /dev/null +++ b/all_pairs/source/ammunition/ammunition_stdlib.h @@ -0,0 +1,6 @@ +#ifndef AMMUNITION_STDLIB_H +#define AMMUNITION_STDLIB_H + +int ammunition_atoi ( const char *str ); + +#endif diff --git a/all_pairs/source/ammunition/ammunition_string.h b/all_pairs/source/ammunition/ammunition_string.h new file mode 100644 index 0000000..6b042f8 --- /dev/null +++ b/all_pairs/source/ammunition/ammunition_string.h @@ -0,0 +1,18 @@ +#ifndef AMMUNITION_STRING_H +#define AMMUNITION_STRING_H + +typedef unsigned int size_x; +//typedef __SIZE_TYPE__ size_x; + +/* + Forward declaration of functions +*/ + +void *ammunition_memcpy( void *, const void *, size_x ); +void *ammunition_memset( void *, int, size_x ); +int ammunition_memcmp ( const void *mem1, const void *mem2, size_x size ); +void *ammunition_memmove ( void *s1, const void *s2, size_x n ); +int ammunition_strcmp ( const char *str1, const char *str2 ); + +#endif /* AMMUNITION_STRING_H */ + diff --git a/all_pairs/source/ammunition/arithm.c b/all_pairs/source/ammunition/arithm.c new file mode 100644 index 0000000..9480846 --- /dev/null +++ b/all_pairs/source/ammunition/arithm.c @@ -0,0 +1,1384 @@ +/* + FILE NAME: arithm.c + + TITLE: Package for arbitrary precision integer arithmetic + + DESCRIPTION: This abstract data implements arbitrary precision + integer and unsigned integer numbers by machine independent + way. The implementation of the package functions are not + sufficiently efficient in order to use for run-time. The + package functions are oriented to implement constant-folding in + compilers. This package is necessary because host machine may + not support such arithmetic for target machine. For example, + VAX does not support does not support more 32-bits integer + numbers arithmetic. The numbers are represented by bytes in + big endian mode, negative integer numbers are represented in + complementary code. All sizes are given in bytes and must be + positive. Results of executions of all functions can coincide + with a operand(s). All functions of addition, subtraction, + multiplication, division, evaluation of remainder, shift, + changing size and transformation of string into number fix + overflow. The overflow is fixed when result can not be + represented by number of given size. + +*/ + +#include "arithm.h" +#include "ammunition_string.h" + + +/* This variable can have only two values 0 or 1. The value `1' + corresponds to overflow. The variable value are modified by all + functions of addition, subtract, multiplication, division, + evaluation of remainder, shift, changing size and transformation of + string into number fix overflow. */ + +int ammunition_overflow_bit; + + +/* The following function adds unsigned integers. The function + returns 1 if unsigned integer overflow is fixed, 0 otherwise. + Result can be placed in any operand. */ + +int ammunition_add_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int digit_num; + int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + sum = ( ( ( unsigned char * ) op1 ) [digit_num] + + ( ( unsigned char * ) op2 ) [digit_num] + carry ); + if ( sum > UCHAR_MAX ) { + sum -= UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = sum; + } + return carry != 0; +} + +/* The following function adds unsigned integers. The function + returns 1 if unsigned integer overflow (the first operand is less + than the second) is fixed, 0 otherwise. Result can be placed in + any operand. */ + +int ammunition_subtract_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int digit_num; + int carry; + int subtraction; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + subtraction = ( ( ( unsigned char * ) op1 ) [digit_num] + - ( ( unsigned char * ) op2 ) [digit_num] - carry ); + if ( subtraction < 0 ) { + subtraction += UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = subtraction; + } + return carry != 0; +} + +/* The following function makes complementary code of number. Result + can be placed in operand. */ + +void ammunition_make_complementary_code +( int size, const void *operand, void *result ) +{ + int digit_num; + int carry; + int subtraction; + + _Pragma( "loopbound min 2 max 6" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + subtraction = ( 0 - ( ( unsigned char * ) operand ) [digit_num] - carry ); + if ( subtraction != 0 ) { + subtraction += UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = subtraction; + } +} + +/* The following function multiplys unsigned integer by digit (byte + size). The function returns 1 if unsigned integer overflow is + fixed, 0 otherwise. */ + +int ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction +( int size, void *operand, unsigned int digit ) +{ + int digit_num; + unsigned int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + sum = ( ( ( unsigned char * ) operand ) [digit_num] * digit + carry ); + if ( sum > UCHAR_MAX ) { + carry = sum / ( UCHAR_MAX + 1 ); + sum %= UCHAR_MAX + 1; + } else + carry = 0; + ( ( unsigned char * ) operand ) [digit_num] = sum; + } + return carry != 0; +} + + +/* Originally reaction on all integer and unsigned integer overflow is + equal to the following function. The function does nothing. */ + +void +ammunition_arithmetic_overflow_reaction ( void ) +{} + + +/* Originally reaction on all integer and unsigned integer overflow is + equal to the following function. The function does nothing. */ + +void +ammunition_arithmetic_unsigned_overflow_reaction ( void ) +{} + + +/* This page contains functions for arbitrary precision addition. */ + +/* The function adds unsigned integers and fixes overflow reaction if + it is needed. The function makes this with the aid of function + `add_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_add_unsigned_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_overflow_bit + = ammunition_add_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function adds integers and fixes overflow reaction if it is + needed. The function makes this with the aid of function + `add_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_add_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int op1_sign; + int sign_equality; + + op1_sign = INTEGER_SIGN ( op1 ); + sign_equality = INTEGER_SIGN ( op1 ) == INTEGER_SIGN ( op2 ); + ammunition_add_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + ammunition_overflow_bit = sign_equality && + ( op1_sign != INTEGER_SIGN ( result ) ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision subtraction. */ + +/* The function subtracts unsigned integers and fixes overflow + reaction if it is needed. The function makes this with the aid of + function `subtract_unsigned_integer_without_overflow_reaction'. + Result can be placed in any operand. */ + +void +ammunition_subtract_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ) +{ + ammunition_overflow_bit + = ammunition_subtract_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function subtracts integers and fixes overflow reaction if it + is needed. The function makes this with the aid of function + `subtract_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_subtract_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int op1_sign; + int sign_unequality; + + op1_sign = INTEGER_SIGN ( op1 ); + sign_unequality = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + ammunition_subtract_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + ammunition_overflow_bit = sign_unequality && + ( op1_sign != INTEGER_SIGN ( result ) ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision multiplication. */ + +/* The following function multiplys unsigned integers. The function + returns 1 if unsigned integer overflow is fixed, 0 otherwise. + Result can be placed in any operand. */ + +int ammunition_multiply_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int op1_digit_num; + int op2_digit_num; + int carry; + unsigned long int partial_sum; + int result_digit_number; + int overflow_flag; + unsigned char long_result [2 * MAX_INTEGER_OPERAND_SIZE]; + + ammunition_memset ( long_result + size, 0, ( size_x ) size ); + _Pragma( "loopbound min 4 max 4" ) + for ( op2_digit_num = size - 1; op2_digit_num >= 0; op2_digit_num-- ) { + if ( ( ( unsigned char * ) op2 ) [op2_digit_num] != 0 ) { + _Pragma( "loopbound min 4 max 4" ) + for ( op1_digit_num = size - 1, carry = 0; op1_digit_num >= 0; + op1_digit_num-- ) { + partial_sum + = ( ( ( unsigned char * ) op1 ) [op1_digit_num] + * ( ( unsigned char * ) op2 ) [op2_digit_num] + + long_result [op1_digit_num + op2_digit_num + 1] + + carry ); + long_result [op1_digit_num + op2_digit_num + 1] + = ( unsigned char ) ( partial_sum % ( UCHAR_MAX + 1 ) ); + carry = partial_sum / ( UCHAR_MAX + 1 ); + } + long_result [op2_digit_num] = carry; + } else + long_result [op2_digit_num] = 0; + } + overflow_flag = 0; + _Pragma( "loopbound min 1 max 4" ) + for ( result_digit_number = size - 1; result_digit_number >= 0; + result_digit_number-- ) { + if ( long_result [result_digit_number] != 0 ) { + overflow_flag = 1; + break; + } + } + ammunition_memcpy ( result, long_result + size, ( size_x ) size ); + return overflow_flag; +} + +/* The following function multiplys unsigned integers and fixes + overflow reaction if it is needed. The function makes this with + the aid of function + `multiply_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_multiply_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ) +{ + ammunition_overflow_bit = + ammunition_multiply_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function multiplys integers and fixes overflow reaction if it + is needed. The function makes this with the aid of function + `multiply_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_multiply_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int negative_result_flag; + unsigned char op1_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned char op2_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned const char *abs_op1; + unsigned const char *abs_op2; + int unsigned_result_sign; + + negative_result_flag = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + if ( INTEGER_SIGN ( op1 ) ) { + /* May be integer overflow. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op1, op1_complementary ); + abs_op1 = ( unsigned const char * )op1_complementary; + } else + abs_op1 = ( unsigned const char * )op1; + if ( INTEGER_SIGN ( op2 ) ) { + /* May be integer overflow. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op2, op2_complementary ); + abs_op2 = ( unsigned const char * )op2_complementary; + } else + abs_op2 = ( unsigned const char * )op2; + ammunition_overflow_bit = + ammunition_multiply_unsigned_integer_without_overflow_reaction ( + size, abs_op1, abs_op2, result ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_result_flag ) + ammunition_make_complementary_code ( size, result, result ); + if ( unsigned_result_sign + && ( !negative_result_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ) + /* Unsigned result can not be represented as integer. */ + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision division. */ + +/* The following function divides unsigned integers. The function + returns 1 if unsigned integer overflow (division by zero) is fixed, + 0 otherwise. Result can be placed in any operand. See algorithm + in Knuth's book. */ + +int ammunition_divide_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int scaled_op1_digit_num; + unsigned int q_approximation; + int first_nonzero_digit_number; + int op2_digit_number; + unsigned int scale; + unsigned char scaled_op1 [MAX_INTEGER_OPERAND_SIZE + 1]; + unsigned char normalized_op2 [MAX_INTEGER_OPERAND_SIZE]; + unsigned char extended_normalized_op2 [MAX_INTEGER_OPERAND_SIZE + 1]; + + _Pragma( "loopbound min 4 max 4" ) + for ( op2_digit_number = 0; op2_digit_number < size; op2_digit_number++ ) { + if ( ( ( unsigned char * ) op2 ) [op2_digit_number] != 0 ) + break; + } + first_nonzero_digit_number = op2_digit_number; + if ( first_nonzero_digit_number == size ) { + /* Zero divisor */ + ammunition_memset ( result, 0, ( size_x ) size ); + return 1 /* TRUE */; + } else + if ( first_nonzero_digit_number == size - 1 ) { + /* Division by digit. */ + int digit_num; + int digit; + unsigned long divisable; + unsigned long remainder; + + digit = ( ( unsigned char * ) op2 ) [first_nonzero_digit_number]; + ammunition_memcpy ( result, op1, ( size_x ) size ); + remainder = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = 0; digit_num < size; digit_num++ ) { + divisable = ( remainder * ( UCHAR_MAX + 1 ) + + ( ( unsigned char * ) result ) [digit_num] ); + remainder = divisable % digit; + ( ( unsigned char * ) result ) [digit_num] + = ( unsigned char ) ( divisable / digit ); + } + return 0 /* FALSE */; + } + /* Normalization of divisor. */ + scale = ( UCHAR_MAX + 1 ) / ( ( ( unsigned char * ) op2 ) [op2_digit_number] + + 1 ); + ammunition_memcpy ( scaled_op1 + 1, op1, ( size_x ) size ); + *scaled_op1 = 0; + + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size + 1, scaled_op1, scale ); + + ammunition_memcpy ( normalized_op2, op2, ( size_x ) size ); + + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size, normalized_op2, scale ); + + _Pragma( "loopbound min 0 max 0" ) + for ( scaled_op1_digit_num = 0; + scaled_op1_digit_num <= first_nonzero_digit_number; + scaled_op1_digit_num++ ) { + /* Division of `scaled_op1[scaled_op1_digit_number]..scaled_op1[size]' by + `normalized_op2[first_nonzero_digit_number]..normalized_op2[size-1]' + for evaluation of one digit of quotient + `result[size-1-first_nonzero_digit_number-scaled_op1_digit_number]'. + */ + if ( scaled_op1 [scaled_op1_digit_num] + == normalized_op2 [first_nonzero_digit_number] ) + q_approximation = UCHAR_MAX; + else + q_approximation + = ( scaled_op1 [scaled_op1_digit_num] * ( UCHAR_MAX + 1 ) + + scaled_op1 [scaled_op1_digit_num + 1] ) + / normalized_op2 [first_nonzero_digit_number]; + + _Pragma( "loopbound min 0 max 0" ) + while ( normalized_op2 [first_nonzero_digit_number + 1] * q_approximation + > ( ( ( unsigned long int ) scaled_op1 [scaled_op1_digit_num] + * ( UCHAR_MAX + 1 ) + + scaled_op1 [scaled_op1_digit_num + 1] + - q_approximation + * normalized_op2 [first_nonzero_digit_number] ) + * ( UCHAR_MAX + 1 ) + scaled_op1 [scaled_op1_digit_num + 2] ) ) + q_approximation --; + + /* Multiply and subtract */ + ammunition_memcpy ( extended_normalized_op2 + 1, + normalized_op2 + first_nonzero_digit_number, + ( size_x ) ( size - first_nonzero_digit_number ) ); + *extended_normalized_op2 = 0; + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, extended_normalized_op2, + q_approximation ); + if ( ammunition_subtract_unsigned_integer_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, + scaled_op1 + scaled_op1_digit_num, extended_normalized_op2, + scaled_op1 + scaled_op1_digit_num ) ) { + /* Negative result. Compensation by addition. */ + q_approximation--; + ammunition_memcpy ( extended_normalized_op2 + 1, + normalized_op2 + first_nonzero_digit_number, + ( size_x ) ( size - first_nonzero_digit_number ) ); + *extended_normalized_op2 = 0; + + ammunition_add_unsigned_integer_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, + scaled_op1 + scaled_op1_digit_num, extended_normalized_op2, + scaled_op1 + scaled_op1_digit_num ); + + } + ( ( unsigned char * ) result ) [size - 1 - first_nonzero_digit_number + + scaled_op1_digit_num] = q_approximation; + } + ammunition_memset ( result, 0, + ( size_x ) ( size - 1 - first_nonzero_digit_number ) ); + return 0 /* TRUE */; +} + +/* The function divides unsigned integers and fixes overflow reaction + if it is needed. The function makes this with the aid of function + `divide_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_divide_unsigned_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_overflow_bit = + ammunition_divide_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function divides integers and fixes overflow reaction if it is + needed. The function makes this with the aid of function + `divide_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_divide_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int negative_result_flag; + unsigned char op1_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned char op2_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned const char *abs_op1; + unsigned const char *abs_op2; + int unsigned_result_sign; + + negative_result_flag = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + if ( INTEGER_SIGN ( op1 ) ) { + /* May be integer overflow for minimal int. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op1, op1_complementary ); + abs_op1 = ( unsigned const char * )op1_complementary; + } else + abs_op1 = ( unsigned const char * )op1; + if ( INTEGER_SIGN ( op2 ) ) { + /* May be integer overflow for minimal int. But result is correct + because it is unsigned. */ + ammunition_make_complementary_code ( size, op2, op2_complementary ); + abs_op2 = ( unsigned const char * )op2_complementary; + } else + abs_op2 = ( unsigned const char * )op2; + ammunition_overflow_bit = + ammunition_divide_unsigned_integer_without_overflow_reaction ( + size, abs_op1, abs_op2, result ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_result_flag ) + ammunition_make_complementary_code ( size, result, result ); + if ( unsigned_result_sign + && ( !negative_result_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ) + /* Unsigned result can not be represented as integer. */ + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision evaluation of + remainder. */ + +/* The function evaluates remainder of division of unsigned integers + as `op1 - (op1/op2)*op2' and fixes overflow reaction if it is + needed. Result can be placed in any operand. */ + +void +ammunition_unsigned_integer_remainder ( int size, const void *op1, + const void *op2, + void *result ) +{ + unsigned char temporary [MAX_INTEGER_OPERAND_SIZE]; + + ammunition_divide_unsigned_integer ( size, op1, op2, temporary ); + if ( ammunition_overflow_bit ) + /* Reaction on zero is called from `divide_unsigned_integer'. */ + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_multiply_unsigned_integer ( size, temporary, op2, temporary ); + ammunition_subtract_unsigned_integer ( size, op1, temporary, result ); + } +} + + +/* This page contains functions for arbitrary precision number shifts. */ + +/* This function makes right shift of unsigned integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `unsigned_integer_shift_left'. The function fixes overflow when + result can not be represented by number of given size, i.e. in + other words the opposite unsigned shift (to left) results in number + not equal to source operand. Result can be placed in operand. */ + +void +ammunition_unsigned_integer_shift_right ( int size, const void *operand, + int bits, void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + + + if ( bits < 0 ) + ammunition_unsigned_integer_shift_left ( size, operand, -bits, result ); + else { + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 3" ) + for ( byte_number = ( byte_shift >= size ? 0 : size - byte_shift ); + byte_number < size; byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( ( char * ) result + byte_shift, operand, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( result, 0, ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 3 max 3" ) + for ( byte_number = byte_shift, carry = 0; byte_number < size; + byte_number++ ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte >> bit_shift ); + carry = ( byte << ( CHAR_BIT - bit_shift ) ) & UCHAR_MAX; + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + } +} + +/* This function makes right arithmetic shift of integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `integer_shift_left'. The function fixes overflow when result can + not be represented by number of given size, i.e. in other words the + opposite shift (to left) results in number not equal to source + operand. Result can be placed in operand. */ + +void +ammunition_integer_shift_right ( int size, const void *operand, int bits, + void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + int operand_sign; + + if ( bits < 0 ) + ammunition_integer_shift_left ( size, operand, -bits, result ); + else { + operand_sign = INTEGER_SIGN ( operand ); + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 3" ) + for ( byte_number = ( byte_shift >= size ? 0 : size - byte_shift ); + byte_number < size; byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, + ( operand_sign ? UCHAR_MAX : 0 ), ( size_x ) size ); + else { + ammunition_memmove ( ( char * ) result + byte_shift, operand, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( result, ( operand_sign ? UCHAR_MAX : 0 ), + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + carry = ( ( ( operand_sign ? UCHAR_MAX : 0 ) << ( CHAR_BIT - bit_shift ) ) + & UCHAR_MAX ); + _Pragma( "loopbound min 3 max 3" ) + for ( byte_number = byte_shift; byte_number < size; byte_number++ ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte >> bit_shift ); + carry = ( byte << ( CHAR_BIT - bit_shift ) ) & UCHAR_MAX; + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); + } +} + +/* This function makes left shift of unsigned integer of given size on + given number of bits. If number of bits is negative the function + makes shift to left actually with the aid of function + `unsigned_integer_shift_right'. The function fixes overflow when + result can not be represented by number of given size, i.e. i.e. in + other words the opposite shift (to right) results in number not + equal to source operand. Result can be placed in operand. */ + +void +ammunition_unsigned_integer_shift_left ( int size, const void *operand, + int bits, void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + + if ( bits < 0 ) + ammunition_unsigned_integer_shift_right ( size, operand, -bits, result ); + else { + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 2" ) + for ( byte_number = 0; byte_number < byte_shift && byte_number < size; + byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( result, ( char * ) operand + byte_shift, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( ( char * ) result + ( size - byte_shift ), 0, + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 2 max 3" ) + for ( byte_number = size - byte_shift - 1, carry = 0; + byte_number >= 0; byte_number-- ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte << bit_shift ); + carry = byte >> ( CHAR_BIT - bit_shift ); + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + } +} + +/* This function makes left arithmetic shift of integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `integer_shift_right'. The function fixes overflow when result can + not be represented by number of given size, i.e. in other words the + opposite shift (to right) results in number not equal to source + operand. Result can be placed in operand. */ + +void +ammunition_integer_shift_left ( int size, const void *operand, int bits, + void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + int operand_sign; + + if ( bits < 0 ) + ammunition_integer_shift_right ( size, operand, -bits, result ); + else { + operand_sign = INTEGER_SIGN ( operand ); + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 2" ) + for ( byte_number = 0; byte_number < byte_shift && byte_number < size; + byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] + != ( operand_sign ? UCHAR_MAX : 0 ) ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( result, ( char * ) operand + byte_shift, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( ( char * ) result + ( size - byte_shift ), 0, + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 2 max 3" ) + for ( byte_number = size - byte_shift - 1, carry = 0; + byte_number >= 0; byte_number-- ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte << bit_shift ); + carry = byte >> ( CHAR_BIT - bit_shift ); + } + if ( carry != ( ( unsigned ) ( operand_sign ? UCHAR_MAX : 0 ) + >> ( CHAR_BIT - bit_shift ) ) ) + ammunition_overflow_bit = 1; + } + if ( operand_sign != INTEGER_SIGN ( result ) ) + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); + } +} + + + +/* This page contains functions for bitwise operations of arbitrary + precision numbers. */ + +/* This function makes bitwise `or' of two integers of given size. */ + +void +ammunition_integer_or ( int size, const void *op1, const void *op2, + void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) op1 ) [byte_number] + | ( ( unsigned char * ) op2 ) [byte_number]; + } +} + +/* This function makes bitwise `or' of two unsigned integers of given + size. */ + +void +ammunition_unsigned_integer_or ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_integer_or ( size, op1, op2, result ); +} + + +/* This function makes bitwise `and' of two integers of given size. */ + +void +ammunition_integer_and ( int size, const void *op1, const void *op2, + void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) op1 ) [byte_number] + & ( ( unsigned char * ) op2 ) [byte_number]; + } +} + +/* This function makes bitwise `and' of two unsigned integers of given + size. */ + +void +ammunition_unsigned_integer_and ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_integer_and ( size, op1, op2, result ); +} + + +/* This function makes bitwise `not' of integer of given size. */ + +void +ammunition_integer_not ( int size, const void *operand, void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) operand ) [byte_number] ^ UCHAR_MAX; + } +} + +/* This function makes bitwise `not' of unsigned integer of given + size. */ + +void +ammunition_unsigned_integer_not ( int size, const void *operand, void *result ) +{ + ammunition_integer_not ( size, operand, result ); +} + + + +/* This page contains functions for comparison of arbitrary precision + numbers. */ + +/* This function compares two unsigned integers of given size on + equality. The function returns 1 if unsigned integers are equal, 0 + otherwise. */ + +int +ammunition_eq_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) == 0; +} + +/* This function compares two integers of given size on equality. The + function returns 1 if integers are equal, 0 otherwise. */ + +int +ammunition_eq_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) == 0; +} + +/* This function compares two unsigned integers of given size on + inequality. The function returns 1 if unsigned integers are not + equal, 0 otherwise. */ + +int +ammunition_ne_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) != 0; +} + +/* This function compares two integers of given size on inequality. + The function returns 1 if integers are not equal, 0 otherwise. */ + +int +ammunition_ne_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) != 0; +} + + +/* This function compares two memory parts of given size on that the + first operand is greater than the second. The bytes are described + as unsigned. The function returns 1 if the first operand is + greater than the second, - 1 if the first operand is less than the + second, 0 otherwise. */ + +int ammunition_bytes_comparison ( const void *op1, const void *op2, int size ) +{ + const unsigned char *str1 = ( unsigned const char * )op1; + const unsigned char *str2 = ( unsigned const char * )op2; + + _Pragma( "loopbound min 1 max 4" ) + while ( size > 0 && *str1 == *str2 ) { + str1++; + str2++; + size--; + } + if ( size <= 0 ) + return 0; + else + if ( *str1 > *str2 ) + return 1; + else + return -1; +} + +/* This function compares two unsigned integers of given size on that + the first operand is greater than the second. The function returns + 1 if the first unsigned integer is greater than the second, 0 + otherwise. */ + +int +ammunition_gt_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) > 0; +} + +/* This function compares two integers of given size on that the first + operand is greater than the second. The function returns 1 if the + first integer is greater than the second, 0 otherwise. */ + +int ammunition_gt_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) > 0; + else + return 1; /* TRUE */ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 0; /*FALSE*/ + else + return ammunition_bytes_comparison ( op1, op2, size ) > 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is less than the second. The function returns 1 + if the first unsigned integer is less than the second, 0 + otherwise. */ + +int +ammunition_lt_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) < 0; +} + +/* This function compares two integers of given size on that the first + operand is less than the second. The function returns 1 if the + first integer is less than the second, 0 otherwise. */ + +int +ammunition_lt_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) < 0; + else + return 0; /*FALSE*/ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 1; /* TRUE */ + else + return ammunition_bytes_comparison ( op1, op2, size ) < 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is greater than or equal to the second. The + function returns 1 if the first unsigned integer is greater than or + equal to the second, 0 otherwise. */ + +int +ammunition_ge_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; +} + +/* This function compares two integers of given size on that the first + operand is greater than or equal to the second. The function + returns 1 if the first integer is greater than or equal to the + second, 0 otherwise. */ + +int +ammunition_ge_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; + else + return 1; /* TRUE */ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 0; /*FALSE*/ + else + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is less than or equal to the second. The + function returns 1 if the first unsigned integer is less than or + equal to the second, 0 otherwise. */ + +int +ammunition_le_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; +} + +/* This function compares two integers of given size on that the first + operand is less than or equal to the second. The function returns + 1 if the first integer is less than or equal to the second, 0 + otherwise. */ + +int +ammunition_le_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; + else + return 0; /*FALSE*/ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 1; /* TRUE */ + else + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; +} + + + +/* This page contains functions for changing size of arbitrary + precision numbers. */ + +/* The function changes size of unsigned integer. The function fixes + overflow when result can not be represented by number of given + size. Result can be placed in operand. */ + +void +ammunition_change_unsigned_integer_size ( int operand_size, const void *operand, + int result_size, void *result ) +{ + int operand_digit_number; + + ammunition_overflow_bit = 0; + if ( operand_size <= result_size ) { + ammunition_memmove ( ( char * ) result + result_size - operand_size, + operand, ( size_x ) operand_size ); + ammunition_memset ( result, 0, ( size_x ) ( result_size - operand_size ) ); + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( operand_digit_number = 0; + operand_digit_number < operand_size - result_size; + operand_digit_number++ ) { + if ( ( ( unsigned char * ) operand ) [operand_digit_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + } + ammunition_memmove ( result, + ( char * ) operand + operand_size - result_size, + ( size_x ) result_size ); + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function changes size of integer. The function fixes overflow + when result can not be represented by number of given size. Result + can be placed in operand. */ + +void +ammunition_change_integer_size ( int operand_size, const void *operand, + int result_size, void *result ) +{ + int operand_digit_number; + int operand_sign; + + ammunition_overflow_bit = 0; + operand_sign = INTEGER_SIGN ( operand ); + if ( operand_size <= result_size ) { + ammunition_memmove ( ( char * ) result + result_size - operand_size, + operand, ( size_x ) operand_size ); + ammunition_memset ( result, ( operand_sign ? UCHAR_MAX : 0 ), + ( size_x ) ( result_size - operand_size ) ); + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( operand_digit_number = 0; + operand_digit_number < operand_size - result_size; + operand_digit_number++ ) { + if ( ( ( unsigned char * ) operand ) [operand_digit_number] + != ( operand_sign ? UCHAR_MAX : 0 ) ) { + ammunition_overflow_bit = 1; + break; + } + } + ammunition_memmove ( result, + ( char * ) operand + operand_size - result_size, + ( size_x ) result_size ); + if ( operand_sign != INTEGER_SIGN ( result ) ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for conversion of arbitrary precision + numbers to ascii representation. */ + +/* This function transforms unsigned integer of given size to BASE + ascii representation. BASE should be between 2 and 36 including + them. Digits more 9 are represented by 'a', 'b' etc. Sign is + absent in result string. The function returns the result + string. */ + +char * +ammunition_unsigned_integer_to_based_string ( int size, const void *operand, + int base, + char *result ) +{ + int digit_num; + int i; + unsigned long divisable; + unsigned long remainder; + int nonzero_flag; + int length; + int temporary; + unsigned char operand_copy [MAX_INTEGER_OPERAND_SIZE]; + + ammunition_memcpy ( operand_copy, operand, ( size_x ) size ); + length = 0; + _Pragma( "loopbound min 1 max 10" ) + do { + nonzero_flag = 0 /* FALSE */; + _Pragma( "loopbound min 2 max 6" ) + for ( digit_num = 0, remainder = 0; digit_num < size; digit_num++ ) { + divisable = remainder * ( UCHAR_MAX + 1 ) + operand_copy [digit_num]; + remainder = divisable % base; + operand_copy [digit_num] = ( unsigned char ) ( divisable / base ); + if ( operand_copy [digit_num] != 0 ) + nonzero_flag = 1 /* TRUE */; + } + result [length++] = ( unsigned char ) ( remainder < 10 ? '0' + remainder + : 'a' + remainder - 10 ); + } while ( nonzero_flag ); + result [length] = '\0'; + _Pragma( "loopbound min 0 max 5" ) + for ( i = 0; i < length / 2; i++ ) { + temporary = result [i]; + result [i] = result [length - i - 1]; + result [length - i - 1] = temporary; + } + return result; +} + + +/* This function transforms unsigned integer of given size to decimal + ascii representation. Sign is absent in result string. The + function returns the result string. */ + +char * +ammunition_unsigned_integer_to_string ( int size, const void *operand, + char *result ) +{ + return ammunition_unsigned_integer_to_based_string ( size, operand, 10, + result ); +} + + +/* This function transforms integer of given size to BASE ascii + representation. BASE should be between 2 and 36 including them. + Digits more 9 are represented by 'a', 'b' etc. Sign is present in + result string only for negative numbers. The function returns the + result string. */ + +char * +ammunition_integer_to_based_string ( int size, const void *operand, int base, + char *result ) +{ + unsigned char operand_copy [MAX_INTEGER_OPERAND_SIZE]; + + if ( !INTEGER_SIGN ( operand ) ) + return ammunition_unsigned_integer_to_based_string ( size, operand, base, + result ); + ammunition_memcpy ( operand_copy, operand, ( size_x ) size ); + /* May be integer overflow. But result is correct because it is unsigned. */ + ammunition_make_complementary_code ( size, operand_copy, operand_copy ); + *result = '-'; + ammunition_unsigned_integer_to_based_string ( size, operand_copy, base, + result + 1 ); + return result; +} + + + +/* This function transforms integer of given size to decimal ascii + representation. Sign is present in result string only for negative + numbers. The function returns the result string. */ + +char * +ammunition_integer_to_string ( int size, const void *operand, char *result ) +{ + return ammunition_integer_to_based_string ( size, operand, 10, result ); +} + +/* This page contains functions for conversion of decimal ascii + representation to arbitrary precision numbers. */ + +/* The function adds digit (byte size) to unsigned integer. The + function returns 1 if unsigned integer overflow is fixed, 0 + otherwise. */ + +int ammunition_add_digit_to_unsigned_integer_without_overflow_reaction +( int size, void *operand, unsigned int digit ) +{ + int digit_num; + unsigned int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = digit; digit_num >= 0; + digit_num-- ) { + sum = ( ( unsigned char * ) operand ) [digit_num] + carry; + if ( sum > UCHAR_MAX ) { + carry = sum / ( UCHAR_MAX + 1 ); + sum %= UCHAR_MAX + 1; + } else + carry = 0; + ( ( unsigned char * ) operand ) [digit_num] = sum; + } + return carry != 0; +} + +/* This function transforms source string (decimal ascii + representation without sign) to given size unsigned integer and + returns pointer to first non digit in the source string through a + parameter. If the string started with invalid integer + representation the result will be zero and returns the operand + through the parameter. The function returns 1 if unsigned integer + overflow is fixed, 0 otherwise. */ + +int ammunition_string_to_unsigned_integer_without_overflow_reaction +( int size, const char *operand, void *result, char **first_nondigit ) +{ + int overflow_flag; + + ammunition_memset ( result, 0, ( size_x ) size ); + _Pragma( "loopbound min 0 max 10" ) + for ( overflow_flag = 0; ammunition_isdigit ( *operand ); operand++ ) { + overflow_flag + = overflow_flag || + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size, result, 10 ); + overflow_flag + = overflow_flag + || ammunition_add_digit_to_unsigned_integer_without_overflow_reaction + ( size, result, *operand - '0' ); + } + *first_nondigit = ( char * ) operand; + return overflow_flag; +} + +/* This function skips all white spaces at the begin of source string + and transforms tail of the source string (decimal ascii + representation without sign) to given size unsigned integer with + the aid of function + `string_to_unsigned_integer_without_overflow_reaction'. If the + string started with invalid unsigned integer representation the + result will be zero. The function fixes overflow when result can + not be represented by number of given size. The function returns + address of the first nondigit in the source string. */ + +char * +ammunition_unsigned_integer_from_string ( int size, const char *operand, + void *result ) +{ + char *first_nondigit; + + _Pragma( "loopbound min 0 max 0" ) + while ( ammunition_isspace ( *operand ) ) + operand++; + ammunition_overflow_bit + = ammunition_string_to_unsigned_integer_without_overflow_reaction + ( size, operand, result, &first_nondigit ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + return first_nondigit; +} + +/* This function skips all white spaces at the begin of source string + and transforms tail of the source string (decimal ascii + representation with possible sign `+' or `-') to given size integer + with the aid of function + `string_to_unsigned_integer_without_overflow_reaction'. If the + string started with invalid integer representation the result will + be zero. The function fixes overflow when result can not be + represented by number of given size. the function returns Address + of the first nondigit in the source string. */ + +char * +ammunition_integer_from_string ( int size, const char *operand, void *result ) +{ + int negative_number_flag; + char *first_nondigit; + int unsigned_result_sign; + + _Pragma( "loopbound min 0 max 0" ) + while ( ammunition_isspace ( *operand ) ) + operand++; + negative_number_flag = 0; /* FALSE */ + if ( *operand == '+' ) + operand++; + else + if ( *operand == '-' ) { + operand++; + negative_number_flag = 1; /* TRUE */ + } + ammunition_overflow_bit + = ammunition_string_to_unsigned_integer_without_overflow_reaction + ( size, operand, result, &first_nondigit ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_number_flag ) + /* May be integer overflow when `result' is correct. But result + is correct because it is unsigned. */ + ammunition_make_complementary_code ( size, result, result ); + ammunition_overflow_bit + = ammunition_overflow_bit + || ( unsigned_result_sign + && ( !negative_number_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + return first_nondigit; +} + diff --git a/all_pairs/source/ammunition/arithm.h b/all_pairs/source/ammunition/arithm.h new file mode 100644 index 0000000..8ed78bf --- /dev/null +++ b/all_pairs/source/ammunition/arithm.h @@ -0,0 +1,123 @@ +/* + FILE NAME: arithm.h + + TITLE: Include file of package for arbitrary precision integer + arithmetic + + DESCRIPTION: This header file contains ANSI C prototype definitions of + the package functions and definitions of external + variable of the package and C++ classes for arbitrary + precision integer arithmetic. + +*/ + + +#ifndef __ARITHMETIC__ +#define __ARITHMETIC__ + +#include "ammunition_limits.h" + + +/* This page contains definitions of variables and macros common for + all package functions. */ + +/* The value of macro is suggested to be maximum length of integer operands + The length of use integers should be not greater than this value. */ + +#define MAX_INTEGER_OPERAND_SIZE 128 + +/* The following macro value is sign of integer number (0 or 1) given + as macro parameter. */ + +#define INTEGER_SIGN(operand) (*(unsigned char *) (operand) >> (CHAR_BIT - 1)) + +extern int ammunition_overflow_bit; + +extern void ammunition_add_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_add_integer ( int size, const void *op1, const void *op2, + void *result ); +extern void ammunition_subtract_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_subtract_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_multiply_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_multiply_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_divide_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_divide_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_unsigned_integer_remainder ( int size, const void *op1, + const void *op2, void *result ); + +extern void ammunition_unsigned_integer_shift_right ( int size, + const void *operand, + int bits, void *result ); +extern void ammunition_integer_shift_right ( int size, const void *operand, + int bits, void *result ); +extern void ammunition_integer_shift_left ( int size, const void *operand, + int bits, void *result ); +extern void ammunition_unsigned_integer_shift_left ( int size, + const void *operand, + int bits, void *result ); + +extern void ammunition_integer_or ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_unsigned_integer_or ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_integer_and ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_unsigned_integer_and ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_integer_not ( int size, const void *operand, + void *result ); +extern void ammunition_unsigned_integer_not ( int size, const void *operand, + void *result ); + +extern int ammunition_eq_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_eq_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_ne_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_ne_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_gt_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_gt_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_lt_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_lt_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_ge_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_ge_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_le_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_le_integer ( int size, const void *op1, const void *op2 ); + +extern void ammunition_change_unsigned_integer_size +( int operand_size, const void *operand, int result_size, void *result ); +extern void ammunition_change_integer_size ( int operand_size, + const void *operand, + int result_size, void *result ); + +extern char *ammunition_unsigned_integer_to_string ( int size, + const void *operand, + char *result ); +extern char *ammunition_integer_to_string ( int size, const void *operand, + char *result ); + +extern char *ammunition_unsigned_integer_from_string ( int size, + const char *operand, + void *result ); +extern char *ammunition_integer_from_string ( int size, const char *operand, + void *result ); + +char ammunition_isdigit( unsigned char c ); +int ammunition_isspace( int c ); + +#endif /* #ifndef __ARITHMETIC__ */ diff --git a/all_pairs/source/ammunition/bits.c b/all_pairs/source/ammunition/bits.c new file mode 100644 index 0000000..9169656 --- /dev/null +++ b/all_pairs/source/ammunition/bits.c @@ -0,0 +1,313 @@ +/* + + FILE NAME: bits.c + + TITLE: Package for work with bits + + DESCRIPTION: This file implements functions of the package for work + with bit strings. A bit is given by address (start address) of + byte from which counting bits starts and its displacement which + is any non negative number of bit from the start address. The + most significant bit of the start address byte has number 0. + The bit string is given by its first bit and its length in + bits. + +*/ + +#include "bits.h" + +/* This function determines that given bit string contains only zero + bits. The function retruns TRUE if all bits of given bit string + are zero or `bit_length' <= 0. Value of `bit_displacement' must be + non-negative and can be greater than CHAR_BIT. */ + +int +ammunition_is_zero_bit_string ( const void *start_byte, int bit_displacement, + int bit_length ) +{ + const unsigned char *current_byte = ( unsigned const char * )start_byte; + + if ( bit_length <= 0 ) + return 1 /* TRUE */; + current_byte += bit_displacement / CHAR_BIT; + bit_displacement %= CHAR_BIT; + if ( bit_length < CHAR_BIT - bit_displacement ) + return ( ( ( *current_byte << bit_displacement ) + & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ) + & UCHAR_MAX ) == 0; + else + if ( bit_displacement != 0 ) { + if ( ( ( *current_byte << bit_displacement ) & UCHAR_MAX ) != 0 ) + return 0 /* FALSE */; + current_byte += 1; + bit_length -= CHAR_BIT - bit_displacement; + } + _Pragma( "loopbound min 0 max 7" ) + while ( bit_length >= CHAR_BIT ) { + if ( *current_byte != 0 ) + return 0 /* FALSE */; + current_byte++; + bit_length -= CHAR_BIT; + } + if ( bit_length > 0 && ( *current_byte >> ( CHAR_BIT - bit_length ) ) != 0 ) + return 0 /* FALSE */; + return 1 /* TRUE */; +} + +/* This function sets up new value of all bits of given bit string. + This function is analog of standard C function `memset'. Value of + `bit_displacement' must be non-negative and can be greater than + CHAR_BIT. */ + +void +ammunition_bit_string_set ( void *start_byte, int bit_displacement, int bit, + int bit_length ) +{ + unsigned char *current_byte = ( unsigned char * )start_byte; + unsigned char filling_byte; + int mask; + + if ( bit_length <= 0 ) + return ; + bit = bit != 0; /* 1 or 0 */ + filling_byte = ( bit ? UCHAR_MAX : 0 ); + current_byte += bit_displacement / CHAR_BIT; + bit_displacement %= CHAR_BIT; + if ( bit_displacement != 0 ) { + mask = UCHAR_MAX << ( CHAR_BIT - bit_displacement ); + if ( bit_length < CHAR_BIT - bit_displacement ) + mask |= UCHAR_MAX >> ( bit_displacement + bit_length ); + *current_byte = ( *current_byte & mask ) | ( filling_byte & ~mask ); + current_byte += 1; + bit_length -= CHAR_BIT - bit_displacement; + } + _Pragma( "loopbound min 0 max 8" ) + while ( bit_length >= CHAR_BIT ) { + *current_byte = filling_byte; + current_byte++; + bit_length -= CHAR_BIT; + } + if ( bit_length > 0 ) + *current_byte + = ( *current_byte & ~( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ) + | ( filling_byte & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string. This + function is analog of standard C function `memcpy'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string must + be non-overlapped. */ + +void +ammunition_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + int byte; + int mask; + + if ( bit_length <= 0 ) + return ; + current_to_byte += to_bit_displacement / CHAR_BIT; + to_bit_displacement %= CHAR_BIT; + current_from_byte += from_bit_displacement / CHAR_BIT; + from_bit_displacement %= CHAR_BIT; + _Pragma( "loopbound min 1 max 8" ) + while ( 1 ) { + byte = ( ( ( *current_from_byte << from_bit_displacement ) & UCHAR_MAX ) + | ( from_bit_displacement != 0 + && bit_length > ( CHAR_BIT - from_bit_displacement ) + ? current_from_byte [1] >> ( CHAR_BIT - from_bit_displacement ) + : 0 ) ); + if ( bit_length <= CHAR_BIT ) + break; + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + *current_to_byte + = ( *current_to_byte + & ( UCHAR_MAX << ( CHAR_BIT - to_bit_displacement ) ) ) + | ( byte >> to_bit_displacement ); + if ( to_bit_displacement != 0 ) + current_to_byte [1] + = ( current_to_byte [1] & ( UCHAR_MAX >> to_bit_displacement ) ) + | ( byte << ( CHAR_BIT - to_bit_displacement ) ); + bit_length -= CHAR_BIT; + current_from_byte++; + current_to_byte++; + } + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + mask = ( ( UCHAR_MAX << ( CHAR_BIT - to_bit_displacement ) ) + | ( UCHAR_MAX >> ( to_bit_displacement + bit_length ) ) ); + *current_to_byte + = ( *current_to_byte & mask ) | ( ( byte >> to_bit_displacement ) & ~mask ); + bit_length -= CHAR_BIT - to_bit_displacement; + if ( bit_length > 0 ) + current_to_byte [1] + = ( current_to_byte [1] & ( UCHAR_MAX >> bit_length ) ) + | ( ( byte << ( CHAR_BIT - to_bit_displacement ) ) + & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string. Copying + starts with the last bits of the bit strings. This function is + used by function `bit_string_move'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string must + be non-overlapped. */ + +void ammunition_reverse_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + int byte; + int mask; + + if ( bit_length <= 0 ) + return ; + to_bit_displacement += bit_length - 1; + current_to_byte += to_bit_displacement / CHAR_BIT; /* last byte */ + to_bit_displacement %= CHAR_BIT; /* last bit */ + from_bit_displacement += bit_length - 1; + current_from_byte += from_bit_displacement / CHAR_BIT; /* last byte */ + from_bit_displacement %= CHAR_BIT; /* last bit */ + _Pragma( "loopbound min 1 max 8" ) + while ( 1 ) { + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + byte = ( ( *current_from_byte >> ( CHAR_BIT - 1 - from_bit_displacement ) ) + | ( ( from_bit_displacement != CHAR_BIT - 1 + && bit_length > from_bit_displacement + 1 + ? current_from_byte [ -1 ] << ( from_bit_displacement + 1 ) + : 0 ) + & UCHAR_MAX ) ); + if ( bit_length <= CHAR_BIT ) + break; + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + *current_to_byte + = ( *current_to_byte & ( UCHAR_MAX >> ( to_bit_displacement + 1 ) ) ) + | ( byte << ( CHAR_BIT - 1 - to_bit_displacement ) ); + if ( to_bit_displacement != CHAR_BIT - 1 ) + current_to_byte [-1] + = ( current_to_byte [-1] + & ( UCHAR_MAX << ( CHAR_BIT - 1 - to_bit_displacement ) ) ) + | ( byte >> ( to_bit_displacement + 1 ) ); + bit_length -= CHAR_BIT; + current_from_byte--; + current_to_byte--; + } + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + mask = ( ( UCHAR_MAX >> ( to_bit_displacement + 1 ) ) | + ( UCHAR_MAX << ( CHAR_BIT - 1 - to_bit_displacement + + bit_length ) ) ); + *current_to_byte + = ( *current_to_byte & mask ) + | ( ( byte << ( CHAR_BIT - 1 - to_bit_displacement ) ) & ~mask ); + bit_length -= to_bit_displacement + 1; + if ( bit_length > 0 ) + current_to_byte [-1] + = ( current_to_byte [-1] & ( UCHAR_MAX << bit_length ) ) + | ( byte >> ( to_bit_displacement + 1 ) + & ( UCHAR_MAX >> ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string with the aid + of functions `bit_string_copy' and `reverse_bit_string_copy'. This + function is analog of standard C function `memmove'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string can + be overlapped. */ + +void +ammunition_bit_string_move ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + + if ( bit_length <= 0 ) + return ; + current_to_byte += to_bit_displacement / CHAR_BIT; + to_bit_displacement %= CHAR_BIT; + current_from_byte += from_bit_displacement / CHAR_BIT; + from_bit_displacement %= CHAR_BIT; + if ( current_from_byte > current_to_byte + || ( current_from_byte == current_to_byte + && from_bit_displacement > to_bit_displacement ) ) + ammunition_bit_string_copy ( current_to_byte, to_bit_displacement, + current_from_byte, from_bit_displacement, + bit_length ); + else + ammunition_reverse_bit_string_copy ( current_to_byte, to_bit_displacement, + current_from_byte, + from_bit_displacement, bit_length ); +} + +/* This function compares bit strings. This function is analog of + standard C function `memcmp'. The function returns 0 if the bit + strings are equal, 1 if the first bit string is greater than the + second, -1 if the first bit string is less than the first. Values + of `bit_displacement1' and `bit_displacement2' must be non-negative + and can be greater than CHAR_BIT. */ + +int +ammunition_bit_string_comparison ( const void *str1, int bit_displacement1, + const void *str2, int bit_displacement2, + int bit_length ) +{ + const unsigned char *current_byte1 = ( unsigned const char * )str1; + const unsigned char *current_byte2 = ( unsigned const char * )str2; + int byte1; + int byte2; + int mask; + + if ( bit_length <= 0 ) + return 0; + current_byte1 += bit_displacement1 / CHAR_BIT; + bit_displacement1 %= CHAR_BIT; + current_byte2 += bit_displacement2 / CHAR_BIT; + bit_displacement2 %= CHAR_BIT; + _Pragma( "loopbound min 1 max 284" ) + while ( 1 ) { + byte1 = ( ( ( *current_byte1 << bit_displacement1 ) & UCHAR_MAX ) + | ( bit_displacement1 != 0 + /* Shift is correct when to_bit_displacement == 0 + because its value is less than word bit size. */ + && bit_length > CHAR_BIT - bit_displacement1 + ? current_byte1 [1] >> ( CHAR_BIT - bit_displacement1 ) + : 0 ) ); + byte2 = ( ( ( *current_byte2 << bit_displacement2 ) & UCHAR_MAX ) + | ( bit_displacement2 != 0 + && bit_length > CHAR_BIT - bit_displacement2 + ? current_byte2 [1] >> ( CHAR_BIT - bit_displacement2 ) + : 0 ) ); + if ( bit_length <= CHAR_BIT ) + break; + if ( byte1 > byte2 ) + return 1; + else + if ( byte1 < byte2 ) + return -1; + bit_length -= CHAR_BIT; + current_byte2++; + current_byte1++; + } + /* Shift is correct when to_bit_displacement == 0 because its value + is less than word bit size. */ + mask = UCHAR_MAX << ( CHAR_BIT - bit_length ); + if ( ( byte1 & mask ) > ( byte2 & mask ) ) + return 1; + else + if ( ( byte1 & mask ) < ( byte2 & mask ) ) + return -1; + else + return 0; +} diff --git a/all_pairs/source/ammunition/bits.h b/all_pairs/source/ammunition/bits.h new file mode 100644 index 0000000..70cf8bd --- /dev/null +++ b/all_pairs/source/ammunition/bits.h @@ -0,0 +1,60 @@ +/* + FILE NAME: bits.h + + TITLE: Include file of package for work with bits + + DESCRIPTION: + This is header file contains macros and the ANSI C prototype + definitions for the package for work with bits and bit strings + and C++ class for work with bits and bit strings. A bit is + given by address (start address) of byte from which counting + bits starts and its displacement which is any non negative + number of bit from the start address. The most significant bit + of the start address byte has number 0. The bit string is + given by its first bit and its length in bits. + +*/ + +#ifndef __BITS__ +#define __BITS__ + +#include "ammunition_limits.h" + +/* This macro value returns bit vlaue (0 or 1) with given bit + displacement (0, 1, ...). The macro has side effects! Value of + `bit_displacement' must be nonegative and can be greater than + CHAR_BIT. */ + +#define BIT(start_byte, bit_displacement)\ + ((((const char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + >> (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)) & 1) + + +/* This macro value sets up new value (must be `0' or `1') of a given + bit (bit displacement starts with 0). The macro has side effects! + Value of `bit_displacement' must be nonegative and can be greater + than CHAR_BIT. */ + +#define SET_BIT(start_byte, bit_displacement, bit)\ + (((char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + = (((char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + & ~(1 << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)))\ + | ((bit) << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT))) + +int ammunition_is_zero_bit_string ( const void *start_byte, + int bit_displacement, + int bit_length ); +void ammunition_bit_string_set ( void *start_byte, int bit_displacement, + int bit, + int bit_length ); +void ammunition_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ); +void ammunition_bit_string_move ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ); +int ammunition_bit_string_comparison ( const void *str1, int bit_displacement1, + const void *str2, int bit_displacement2, + int bit_length ); + +#endif /* #ifndef __BITS__ */ diff --git a/all_pairs/source/ammunition/gmon.out b/all_pairs/source/ammunition/gmon.out new file mode 100644 index 0000000..2d07b7f Binary files /dev/null and b/all_pairs/source/ammunition/gmon.out differ diff --git a/all_pairs/source/ammunition/timeScript b/all_pairs/source/ammunition/timeScript new file mode 100644 index 0000000..33ba812 --- /dev/null +++ b/all_pairs/source/ammunition/timeScript @@ -0,0 +1,8 @@ +#!/bin/bash +startTime=$(date +%N) +echo start time $startTime +$1 +stopTime=$(date +%N) +echo stop time $stopTime +totalTime=`expr $stopTime - $startTime` +echo total time $totalTime diff --git a/all_pairs/source/anagram/ChangeLog.txt b/all_pairs/source/anagram/ChangeLog.txt new file mode 100644 index 0000000..fdba1cc --- /dev/null +++ b/all_pairs/source/anagram/ChangeLog.txt @@ -0,0 +1,125 @@ +File: anagram.c +Original provenience: unknown +Source: unknown + +2017-04-18: +- Annotated anagram_main as entry-point for timing analysis + +2016-06-22: +- Fixed type signature of function anagram_main to conform to TACLeBench + standard, i.e. `void anagram_main (void)`. + +2016-05-24: +- Changed type of global variables anagram_achPhrase and + anagram_dictionary to `char const *[]`. +- Changed parameter type of function anagram_BuildMask to + `char const *`. + +2016-04-26: +- Fixed array out-of-bounds access introduced by earlier change. + +2016-04-20: +- Fixed some compiler warnings. +- Return value of anagram_return depends on the computation inside + of anagram_main. + +2016-03-22 +- Added forward declarations for all functions. +- Renamed function main to anagram_main. +- Added function anagram_init that calls anagram_ReadDict, removed + call to anagram_ReadDict from anagram_main. +- Added function anagram_return that handles the return value. +- Added new function main that first calls anagram_init, + then anagram_main and finally returns the return value of + anagram_return. +- Added generic TACLeBench header to all files. +- Introduced comments to split file in sections for type + definitions, forward declarations, global variables, + initialization-related and return-value-related functions, + core benchmark functions, and main routine. +- Renamed ch2i, DICTWORDS, Quad, MASK_BITS, MAX_QUADS, MAXCAND, + MAXSOL, ALPHABET, Word, PWord, PPWord, apwCand, cpwCand, Letter, + PLetter, alPhrase, cchPhraseLength, aqMainMask, aqMainSign, + cchMinLength, auGlobalFrequency, achByFrequency, pchDictionary, + Reset, ReadDict, BuildMask, NewWord, NextWord, BuildWord, + AddWords, apwSol, cpwLast, OneStep, DumpWords, FindAnagram and + SortCandidates to anagram_ch2i, anagram_DICTWORDS, anagram_Quad, + anagram_MASK_BITS, anagram_MAX_QUADS, anagram_MAXCAND, + anagram_MAXSOL, anagram_ALPHABET, anagram_Word, anagram_PWord, + anagram_PPWord, anagram_apwCand, anagram_cpwCand, anagram_Letter, + anagram_PLetter, anagram_alPhrase, anagram_cchPhraseLength, + anagram_aqMainMask, anagram_aqMainSign, anagram_cchMinLength, + anagram_auGlobalFrequency, anagram_achByFrequency, + anagram_pchDictionary, anagram_Reset, anagram_ReadDict, + anagram_BuildMask, anagram_NewWord, anagram_NextWord, + anagram_BuildWord, anagram_AddWords, anagram_apwSol, + anagram_cpwLast, anagram_OneStep, anagram_DumpWords, + anagram_FindAnagram and anagram_SortCandidates. +- Renamed swapi, pivot, qsorts, simulated_heap and freeHeapPos to + anagram_swapi, anagram_pivot, anagram_qsorts, + anagram_simulated_heap and anagram_freeHeapPos. +- Renamed achPhrase and dictionary to anagram_achPhrase and + anagram_dictionary. +- Renamed CompareFrequency to anagram_CompareFrequency. +- Increased simulated heap in anagram_stdlib.c to 18000 bytes to + prevent segmentation fault. +- Changed header guard _WCCMALLOC_H to ANAGRAM_STRINGS_H. +- Renamed wccmalloc, wccbzero to anagram_malloc, anagram_bzero. +- Moved declaration of anagram_malloc to header anagram_stdlib.h. +- Introduced header guard ANAGRAM_CTYPE_H. +- Renamed wccislower, wccisupper, wccisalpha, wcctolower to + anagram_islower, anagram_isupper, anagram_isalpha, + anagram_tolower. +- Removed illegal keyword "inline". +- Changed header guard _WCCSTDLIB_H to ANAGRAM_STDLIB_H. +- Renamed wccqsort to anagram_qsort. +- Fixed compiler warning "no previous extern declaration for + non-static variable" for variables simulated_heap and + freeHeapPos by declaring them static. +- Renamed preprocessor define HEAP_SIZE to ANAGRAM_HEAP_SIZE. +- Fixed compiler warning "no previous prototype for function" by + moving includes to the top of the file. +- Fixed compiler warnings "implicit conversion changes signedness" + and "comparison of integers of different signs" by consistenly + using the type unsigned long in qsort helper functions. +- Moved function CompareFrequency to file anagram.c, added + declaration for it in file anagram_compare.h and included it in + anagram_stdlib.h. +- Fixed compiler warning "no previous extern declaration for + non-static variable" by adding forward declarations. +- Fixed compiler warning "macro is not used" by removing unused + macros MAXWORDS and i2ch. +- Replaced macro ch2i by proper function. +- Fixed compiler warning "array subscript is of type 'char' in + function CompareFrequency. +- Fixed compiler warning "unused variable" by removing variable i + in function Reset. +- Fixed compiler warning "no previous extern declaration for + non-static variable" by making global variables in file + anagram.c static. +- Replaced macro lPhrase by its expansion. +- Fixed compiler warnings "implicit conversion loses integer + precision" and "implicit conversion changes signedness" by + adding explicit casts or using the appropriate type for local + variables. +- Fixed compiler warning "array subscript is of type 'char'" by + changing type of some local variables as well as of global + variable achByFrequency to int. +- Changed all //-style comments to /* */-style comments. +- Moved contents of wccmalloc.c to anagram_stdlib.c. +- Renamed input.c to anagram_input.c. +- Renamed wccctype.h to anagram_ctype.h. +- Renamed wccstdlib.c to anagram_stdlib.c. +- Renamed wccstdlib.h to anagram_stdlib.h. +- Renamed wccmalloc.h to anagram_strings.h. +- Applied TACLeBench formatting rules via + astyle --options=doc/example/astylerc.txt +- Tested conformance to C99 via + clang -fsyntax-only -Weverything -Wno-unknown-pragmas -Wno-padded -pedantic -std=c99 + +2017-06-27 +- Remove static declarations. + +2017-07-10: +- Adjust alignment calculation in anagram_malloc to not add padding on already + aligned addresses. This prevents a buffer overflow of anagram_simulated_heap. diff --git a/all_pairs/source/anagram/anagram.c b/all_pairs/source/anagram/anagram.c new file mode 100644 index 0000000..8f140a3 --- /dev/null +++ b/all_pairs/source/anagram/anagram.c @@ -0,0 +1,670 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version 2.0 + + Name: anagram + + Author: Raymond Chen + + Function: A program that computes anagrams. + + Source: See below. + + Original name: anagram + + Changes: See ChangeLog.txt + + License: See below. + +*/ + +/* + Anagram program by Raymond Chen, + inspired by a similar program by Brian Scearce + + This program is Copyright 1991 by Raymond Chen. + (rjc@math.princeton.edu) + + This program may be freely distributed provided all alterations + to the original are clearly indicated as such. +*/ + +/* There are two tricks. First is the Basic Idea: + + When the user types in a phrase, the phrase is first preprocessed to + determine how many of each letter appears. A bit field is then constructed + dynamically, such that each field is large enough to hold the next power + of two larger than the number of times the character appears. For example, + if the phrase is hello, world, the bit field would be + + 00 00 00 000 000 00 00 + d e h l o r w + + The phrase hello, world, itself would be encoded as + + 01 01 01 011 010 01 01 + d e h l o r w + + and the word hollow would be encoded as + + 00 00 01 010 010 00 01 + d e h l o r w + + The top bit of each field is set in a special value called the sign. + Here, the sign would be + + 10 10 10 100 100 10 10 + d e h l o r w + + + The reason for packing the values into a bit field is that the operation + of subtracting out the letters of a word from the current phrase can be + carried out in parallel. for example, subtracting the word hello from + the phrase hello, world, is merely + + d e h l o r w + 01 01 01 011 010 01 01 (dehllloorw) + - 00 00 01 010 010 00 01 (hlloow) + ======================== + 01 01 00 001 000 01 00 (delr) + + Since none of the sign bits is set, the word fits, and we can continue. + Suppose the next word we tried was hood. + + d e h l o r w + 01 01 00 001 000 01 00 (delr) + - 01 00 01 000 010 00 00 (hood) + ======================== + 00 00 11 000 110 01 00 + ^ ^ + A sign bit is set. (Two, actually.) This means that hood does not + fit in delr, so we skip it and try another word. (Observe that + when a sign bit becomes set, it screws up the values for the letters to + the left of that bit, but that's not important.) + + The inner loop of an anagram program is testing to see if a + word fits in the collection of untried letters. Traditional methods + keep an array of 26 integers, which are then compared in turn. This + means that there are 26 comparisons per word. + + This method reduces the number of comparisons to MAX_QUAD, typically 2. + Instead of looping through an array, we merely perform the indicated + subtraction and test if any of the sign bits is set. +*/ + +/* The nuts and bolts: + + The dictionary is loaded and preprocessed. The preprocessed dictionary + is a concatenation of copies of the structure: + + struct dictword { + char bStructureSize; -- size of this structure + char cLetters; -- number of letters in the word + char achWord[]; -- the word itself (0-terminated) + } + + Since this is a variable-sized structure, we keep its size in the structure + itself for rapid stepping through the table. + + When a phrase is typed in, it is first preprocessed as described in the + Basic Idea. We then go through the dictionary, testing each word. If + the word fits in our phrase, we build the bit field for its frequency + table and add it to the list of candidates. +*/ + +/* + The Second Trick: + + Before diving into our anagram search, we then tabulate how many times + each letter appears in our list of candidates, and sort the table, with + the rarest letter first. + + We then do our anagram search. + + Like most anagram programs, this program does a depth-first search. + Although most anagram programs do some sort of heuristics to decide what + order to place words in the list_of_candidates, the search itself proceeds + according to a greedy algorithm. That is, once you find a word that fits, + subtract it and recurse. + + This anagram program exercises some restraint and does not march down + every branch that shows itself. Instead, it only goes down branches + that use the rarest unused letter. This helps to find dead ends faster. + + FindAnagram(unused_letters, list_of_candidates) { + l = the rarest letter as yet unused + For word in list_of_candidates { + if word does not fit in unused_letters, go on to the next word. + if word does not contain l, defer. + FindAnagram(unused_letters - word, list_of_candidates[word,...]) + } + } + + + The heuristic of the Second Trick can probably be improved. I invite + anyone willing to improve it to do so. +*/ + +/* Before compiling, make sure Quad and MASK_BITS are set properly. For best + results, make Quad the largest integer size supported on your machine. + So if your machine has long longs, make Quad an unsigned long long. + (I called it Quad because on most machines, the largest integer size + supported is a four-byte unsigned long.) + + If you need to be able to anagram larger phrases, increase MAX_QUADS. + If you increase it beyond 4, you'll have to add a few more loop unrolling + steps to FindAnagram. +*/ + +#include "../extra.h" +#include "anagram_ctype.h" +#include "anagram_stdlib.h" +#include "anagram_strings.h" + +#include "anagram_compare.h" + + +/* + Defines +*/ + +#define anagram_DICTWORDS 2279 +#define anagram_MASK_BITS 32 /* number of bits in a Quad */ +#define anagram_MAX_QUADS 2 /* controls largest phrase */ +#define anagram_MAXCAND 100 /* candidates */ +#define anagram_MAXSOL 51 /* words in the solution */ +#define anagram_ALPHABET 26 /* letters in the alphabet */ + +#define anagram_OneStep( i ) \ + if ( ( aqNext[ i ] = pqMask[ i ] - pw->aqMask[ i ] ) & anagram_aqMainSign[ i ] ) { \ + ppwStart ++; \ + continue; \ + } + + +/* + Type definitions +*/ + +typedef unsigned int anagram_Quad; /* for building our bit mask */ + +/* A Word remembers the information about a candidate word. */ +typedef struct { + char *pchWord; /* the word itself */ + anagram_Quad aqMask[ anagram_MAX_QUADS ]; /* the word's mask */ + unsigned cchLength; /* letters in the word */ + char padding[4]; +} anagram_Word; +typedef anagram_Word *anagram_PWord; +typedef anagram_Word **anagram_PPWord; + +/* A Letter remembers information about each letter in the phrase to + be anagrammed. */ +typedef struct { + unsigned uFrequency; /* how many times it appears */ + unsigned uShift; /* how to mask */ + unsigned uBits; /* the bit mask itself */ + unsigned iq; /* which Quad to inspect? */ +} anagram_Letter; +typedef anagram_Letter *anagram_PLetter; + + +/* + Forward declaration of functions +*/ + +void anagram_init( void ); +void anagram_main( void ); +int anagram_return( void ); +int anagram_ch2i( int ch ); +void anagram_AddWords( void ); +void anagram_BuildMask( char const *pchPhrase ); +void anagram_BuildWord( char *pchWord ); +void anagram_DumpWords( void ); +void anagram_FindAnagram( anagram_Quad *pqMask, + anagram_PPWord ppwStart, + int iLetter ); +anagram_PWord anagram_NewWord( void ); +anagram_PWord anagram_NextWord( void ); +void anagram_ReadDict( void ); +void anagram_Reset( void ); +void anagram_SortCandidates( void ); + + +/* + Declaration of global variables +*/ + +extern char const *anagram_achPhrase[ 3 ]; +extern char const *anagram_dictionary[ anagram_DICTWORDS ]; + +/* candidates we've found so far */ +static anagram_PWord anagram_apwCand[ anagram_MAXCAND ]; +/* how many of them? */ +static unsigned anagram_cpwCand; + +/* statistics on the current phrase */ +static anagram_Letter anagram_alPhrase[ anagram_ALPHABET ]; + +/* number of letters in phrase */ +static int anagram_cchPhraseLength; + +/* the bit field for the full phrase */ +static anagram_Quad anagram_aqMainMask[ anagram_MAX_QUADS ]; +/* where the sign bits are */ +static anagram_Quad anagram_aqMainSign[ anagram_MAX_QUADS ]; + +static const int anagram_cchMinLength = 3; + +/* auGlobalFrequency counts the number of times each letter appears, + summed over all candidate words. This is used to decide which letter + to attack first. */ +static unsigned anagram_auGlobalFrequency[ anagram_ALPHABET ]; +static int anagram_achByFrequency[ anagram_ALPHABET ]; /* for sorting */ + +/* the dictionary is read here */ +static char *anagram_pchDictionary; + +/* the answers */ +static anagram_PWord anagram_apwSol[ anagram_MAXSOL ]; +static int anagram_cpwLast; + +/* buffer to write an answer */ +static char anagram_buffer[30]; + +/* + Initialization- and return-value-related functions +*/ + +/* ReadDict -- read the dictionary file into memory and preprocess it + + A word of length cch in the dictionary is encoded as follows: + + byte 0 = cch + 3 + byte 1 = number of letters in the word + byte 2... = the word itself, null-terminated + + Observe that cch+3 is the length of the total encoding. These + byte streams are concatenated, and terminated with a 0. +*/ +void anagram_ReadDict( void ) +{ + char *pch; + char *pchBase; + unsigned len; + unsigned cWords = 0; + unsigned cLetters; + int i; + volatile char bitmask = 0; + + len = 0; + _Pragma( "loopbound min 2279 max 2279" ) + for ( i = 0; i < anagram_DICTWORDS; i ++ ) { + unsigned strlen = 0; + _Pragma( "loopbound min 1 max 5" ) + while ( anagram_dictionary[ i ][ strlen ] != 0 ) + strlen ++; + len += strlen + 2; + } + + pchBase = anagram_pchDictionary = ( char * )anagram_malloc( len ); + + _Pragma( "loopbound min 2279 max 2279" ) + for ( i = 0; i < anagram_DICTWORDS; i ++ ) { + int index = 0; + pch = pchBase + 2; /* reserve for length */ + cLetters = 0; + + _Pragma( "loopbound min 1 max 5" ) + while ( anagram_dictionary[ i ][ index ] != '\0' ) { + if ( anagram_isalpha( anagram_dictionary[ i ][ index ] ) ) + cLetters ++; + *pch ++ = anagram_dictionary[ i ][ index ]; + index ++; + *( pch - 1 ) ^= bitmask; + } + *pch ++ = '\0'; + *pchBase = ( char )( pch - pchBase ); + pchBase[ 1 ] = ( char )cLetters; + pchBase = pch; + cWords ++; + } + + *pchBase ++ = 0; +} + + +void anagram_init( void ) +{ + anagram_ReadDict(); +} + + +int anagram_return( void ) +{ + int i; + char const *answer = "duke rip amy"; + + for ( i = 0; i < 12; i++ ) + if ( answer[ i ] != anagram_buffer[ i ] ) + return 1; + + return 0; +} + + +/* + Core benchmark functions +*/ + +/* convert letter to index */ +int anagram_ch2i( int ch ) +{ + return ch - 'a'; +} + + +int anagram_CompareFrequency( char *pch1, char *pch2 ) +{ + return anagram_auGlobalFrequency[ ( (int) *pch1 ) ] < + anagram_auGlobalFrequency[ ( (int) *pch2 ) ] + ? -1 : + anagram_auGlobalFrequency[ ( (int) *pch1 ) ] == + anagram_auGlobalFrequency[ ( (int) *pch2 ) ] + ? 0 : 1; +} + + +void anagram_Reset( void ) +{ + anagram_bzero( ( char * )anagram_alPhrase, + sizeof( anagram_Letter ) * anagram_ALPHABET ); + anagram_bzero( ( char * )anagram_aqMainMask, + sizeof( anagram_Quad ) * anagram_MAX_QUADS ); + anagram_bzero( ( char * )anagram_aqMainSign, + sizeof( anagram_Quad ) * anagram_MAX_QUADS ); + anagram_bzero( ( char * )anagram_auGlobalFrequency, + sizeof( unsigned ) * anagram_ALPHABET ); + anagram_bzero( ( char * )anagram_achByFrequency, + sizeof( int ) * anagram_ALPHABET ); + anagram_bzero( ( char * )anagram_apwCand, + sizeof( anagram_PWord ) * anagram_MAXCAND ); + anagram_cchPhraseLength = 0; + anagram_cpwCand = 0; +} + + +void anagram_BuildMask( char const *pchPhrase ) +{ + int i; + int ch; + unsigned iq; /* which Quad? */ + unsigned int cbtUsed; /* bits used in the current Quad */ + unsigned int cbtNeed; /* bits needed for current letter */ + anagram_Quad qNeed; /* used to build the mask */ + + /* Tabulate letter frequencies in the phrase */ + anagram_cchPhraseLength = 0; + _Pragma( "loopbound min 11 max 12" ) + while ( ( ch = *pchPhrase ++ ) != '\0' ) { + if ( anagram_isalpha( ch ) ) { + ch = anagram_tolower( ch ); + anagram_alPhrase[ anagram_ch2i( ch ) ].uFrequency ++; + anagram_cchPhraseLength ++; + } + } + + /* Build masks */ + iq = 0; /* which quad being used */ + cbtUsed = 0; /* bits used so far */ + + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) { + if ( anagram_alPhrase[ i ].uFrequency == 0 ) { + anagram_auGlobalFrequency[ i ] = ~0u; /* to make it sort last */ + } else { + anagram_auGlobalFrequency[ i ] = 0u; + _Pragma( "loopbound min 1 max 2" ) + for ( cbtNeed = 1, qNeed = 1; + anagram_alPhrase[ i ].uFrequency >= qNeed; + cbtNeed ++, qNeed <<= 1 ) + ; + if ( cbtUsed + cbtNeed > anagram_MASK_BITS ) + cbtUsed = 0; + anagram_alPhrase[ i ].uBits = qNeed - 1; + if ( cbtUsed ) + qNeed <<= cbtUsed; + anagram_aqMainSign[ iq ] |= qNeed; + anagram_aqMainMask[ iq ] |= + ( anagram_Quad )anagram_alPhrase[ i ].uFrequency << cbtUsed; + anagram_alPhrase[ i ].uShift = cbtUsed; + anagram_alPhrase[ i ].iq = iq; + cbtUsed += cbtNeed; + } + } +} + + +anagram_PWord anagram_NewWord( void ) +{ + anagram_PWord pw; + + pw = ( anagram_Word * )anagram_malloc( sizeof( anagram_Word ) ); + return pw; +} + + +/* NextWord -- get another candidate entry, creating if necessary */ +anagram_PWord anagram_NextWord( void ) +{ + anagram_PWord pw; + pw = anagram_apwCand[ anagram_cpwCand ++ ]; + if ( pw != 0 ) + return pw; + anagram_apwCand[ anagram_cpwCand - 1 ] = anagram_NewWord(); + return anagram_apwCand[ anagram_cpwCand - 1 ]; +} + + +/* BuildWord -- build a Word structure from an ASCII word + If the word does not fit, then do nothing. */ +void anagram_BuildWord( char *pchWord ) +{ + unsigned char cchFrequency[ anagram_ALPHABET ]; + int i; + char *pch = pchWord; + anagram_PWord pw; + unsigned int cchLength = 0; + + anagram_bzero( ( char * )cchFrequency, + sizeof( unsigned char ) * anagram_ALPHABET ); + + /* Build frequency table */ + _Pragma( "loopbound min 3 max 636" ) + while ( ( i = *pch ++ ) != '\0' ) { + if ( !anagram_isalpha( i ) ) + continue; + i = anagram_ch2i( anagram_tolower( i ) ); + if ( ++ cchFrequency[ i ] > anagram_alPhrase[ i ].uFrequency ) + return ; + ++ cchLength; + } + + /* Update global count */ + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) + anagram_auGlobalFrequency[ i ] += cchFrequency[ i ]; + + /* Create a Word structure and fill it in, including building the + bitfield of frequencies. */ + pw = anagram_NextWord(); + anagram_bzero( ( char * )( pw->aqMask ), + sizeof( anagram_Quad ) * anagram_MAX_QUADS ); + + pw->pchWord = pchWord; + pw->cchLength = cchLength; + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) { + pw->aqMask[ anagram_alPhrase[i].iq ] |= + ( anagram_Quad )cchFrequency[ i ] << anagram_alPhrase[ i ].uShift; + } +} + + +/* AddWords -- build the list of candidates */ +void anagram_AddWords( void ) +{ + char *pch = anagram_pchDictionary; /* walk through the dictionary */ + + anagram_cpwCand = 0; + + _Pragma( "loopbound min 1967 max 1967" ) + while ( *pch ) { + if ( ( pch[ 1 ] >= anagram_cchMinLength && + pch[ 1 ] + anagram_cchMinLength <= anagram_cchPhraseLength ) + || pch[ 1 ] == anagram_cchPhraseLength ) + anagram_BuildWord( pch + 2 ); + pch += *pch; + } +} + + +void anagram_DumpWords( void ) +{ + int i, j; + int offset = 0; + _Pragma( "loopbound min 3 max 3" ) + for ( i = 0; i < anagram_cpwLast; i ++ ) { + _Pragma( "loopbound min 3 max 5" ) + for ( j = 0; anagram_apwSol[ i ]->pchWord[ j ] != '\0'; j ++ ) + anagram_buffer[ offset + j ] = anagram_apwSol[ i ]->pchWord[ j ]; + offset += j; + + anagram_buffer[ offset ++ ] = ' '; + } + anagram_buffer[ offset ++ ] = '\0'; +} + + +void anagram_FindAnagram( anagram_Quad *pqMask, anagram_PPWord ppwStart, + int iLetter ) +{ + anagram_Quad aqNext[ anagram_MAX_QUADS ]; + register anagram_PWord pw; + anagram_Quad qMask; + unsigned iq; + anagram_PPWord ppwEnd = &anagram_apwCand[ 0 ]; + ppwEnd += anagram_cpwCand; + + _Pragma( "loopbound min 1 max 7" ) + while ( 1 ) { + iq = anagram_alPhrase[ anagram_achByFrequency[iLetter] ].iq; + qMask = anagram_alPhrase[ anagram_achByFrequency[iLetter] ].uBits << + anagram_alPhrase[ anagram_achByFrequency[iLetter] ].uShift; + if ( pqMask[ iq ] & qMask ) + break; + iLetter ++; + } + + _Pragma( "loopbound min 0 max 114" ) + while ( ppwStart < ppwEnd ) { + pw = *ppwStart; + + #if anagram_MAX_QUADS > 0 + anagram_OneStep( 0 ); + #endif + + #if anagram_MAX_QUADS > 1 + anagram_OneStep( 1 ); + #endif + + #if anagram_MAX_QUADS > 2 + anagram_OneStep( 2 ); + #endif + + #if anagram_MAX_QUADS > 3 + anagram_OneStep( 3 ); + #endif + + #if anagram_MAX_QUADS > 4 + @@"Add more unrolling steps here, please."@@ + #endif + + /* If the pivot letter isn't present, defer this word until later */ + if ( ( pw->aqMask[ iq ] & qMask ) == 0 ) { + *ppwStart = *( -- ppwEnd ); + *ppwEnd = pw; + continue; + } + + /* If we get here, this means the word fits. */ + anagram_apwSol[ anagram_cpwLast ++ ] = pw; + if ( anagram_cchPhraseLength -= pw->cchLength ) { /* recurse */ + /* The recursive call scrambles the tail, so we have to be + pessimistic. */ + ppwEnd = &anagram_apwCand[ 0 ]; + ppwEnd += anagram_cpwCand; + anagram_FindAnagram( &aqNext[ 0 ], ppwStart, iLetter ); + } else { /* found one */ + anagram_DumpWords(); + } + anagram_cchPhraseLength += pw->cchLength; + -- anagram_cpwLast; + ppwStart ++; + continue; + } +} + + +void anagram_SortCandidates( void ) +{ + int i; + + /* Sort the letters by frequency */ + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) + anagram_achByFrequency[ i ] = i; + anagram_qsort( anagram_achByFrequency, anagram_ALPHABET, sizeof( int ) ); +} + + +void _Pragma( "entrypoint" ) anagram_main( void ) +{ + int i; + + _Pragma( "loopbound min 3 max 3" ) + for ( i = 0; i < 3; i ++ ) { + anagram_Reset(); + anagram_BuildMask( anagram_achPhrase[ i ] ); + anagram_AddWords(); + if ( anagram_cpwCand == 0 || anagram_cchPhraseLength == 0 ) + continue; + + anagram_cpwLast = 0; + anagram_SortCandidates(); + _Pragma( "marker call_find" ) + anagram_FindAnagram( anagram_aqMainMask, anagram_apwCand, 0 ); + _Pragma( "flowrestriction 1*anagram_FindAnagram <= 51*call_find" ) + } +} + + +/* + Main function +*/ + +int main(int argc, char **argv) +{ + SET_UP + //int jobsComplete; + //int maxJobs=100; + //for(jobsComplete=-1; jobsComplete 1 ) { + if ( n > 10 ) + pi = anagram_pivot( a, n, es ); + else + pi = a + ( n >> 1 ) * es; + + anagram_swapi( a, pi, es ); + pi = a; + pn = a + n * es; + pj = pn; + _Pragma( "loopbound min 1 max 11" ) + while ( 1 ) { + /* wcc note: this assignment expression was added to avoid assignment of + multiple loop bound annotations to same loop (cf. Ticket #0002323). */ + flowfactdummy ++; + _Pragma( "loopbound min 1 max 5" ) + do { + pi += es; + } while ( pi < pn && anagram_CompareFrequency( pi, a ) < 0 ); + _Pragma( "loopbound min 1 max 4" ) + do { + pj -= es; + } while ( pj > a && anagram_CompareFrequency( pj, a ) > 0 ); + if ( pj < pi ) + break; + anagram_swapi( pi, pj, es ); + } + anagram_swapi( a, pj, es ); + j = ( unsigned long )( pj - a ) / es; + + n = n - j - 1; + if ( j >= n ) { + anagram_qsorts( a, j, es ); + a += ( j + 1 ) * es; + } else { + anagram_qsorts( a + ( j + 1 )*es, n, es ); + n = j; + } + } +} + +void anagram_qsort( void *va, unsigned long n, unsigned long es ) +{ + _Pragma( "marker call_qsorts" ) + anagram_qsorts( ( char * )va, n, es ); + _Pragma( "flowrestriction 1*anagram_qsorts <= 17*call_qsorts" ) +} + + +/* This must be redefined for each new benchmark */ +#define ANAGRAM_HEAP_SIZE 18000 + +static char anagram_simulated_heap[ANAGRAM_HEAP_SIZE]; +static unsigned int anagram_freeHeapPos; + +void *anagram_malloc( unsigned int numberOfBytes ) +{ + void *currentPos = ( void * )&anagram_simulated_heap[ anagram_freeHeapPos ]; + /* Get a 4-byte address for alignment purposes */ + //anagram_freeHeapPos += ( ( numberOfBytes + 4 ) & ( unsigned int )0xfffffffc ); + unsigned int rem = (numberOfBytes & ( unsigned int )0x3 ); + unsigned int adjustment = rem ? 4 - rem : 0; + anagram_freeHeapPos += numberOfBytes + adjustment; + return currentPos; +} + +void anagram_bzero( char *p, unsigned long len ) +{ + unsigned long i; + + _Pragma( "loopbound min 8 max 416" ) + for ( i = 0; i < len; ++ i ) + *p ++ = '\0'; +} + diff --git a/all_pairs/source/anagram/anagram_stdlib.h b/all_pairs/source/anagram/anagram_stdlib.h new file mode 100644 index 0000000..0e745d5 --- /dev/null +++ b/all_pairs/source/anagram/anagram_stdlib.h @@ -0,0 +1,29 @@ +/* + + This header is part of the TACLeBench benchmark suite. + Version 2.0 + + Name: anagram_stdlib.h + + Author: Raymond Chen + + Function: This header contains some C standard library functions used by anagram. + + Source: unknown + + Original name: anagram + + Changes: See ChangeLog.txt + + License: See anagram.c + +*/ + +#ifndef ANAGRAM_STDLIB_H +#define ANAGRAM_STDLIB_H + +void *anagram_malloc( unsigned int numberOfBytes ); + +void anagram_qsort( void *va, unsigned long n, unsigned long es ); + +#endif diff --git a/all_pairs/source/anagram/anagram_strings.h b/all_pairs/source/anagram/anagram_strings.h new file mode 100644 index 0000000..1e023fc --- /dev/null +++ b/all_pairs/source/anagram/anagram_strings.h @@ -0,0 +1,27 @@ +/* + + This header is part of the TACLeBench benchmark suite. + Version 2.0 + + Name: anagram_strings.h + + Author: Raymond Chen + + Function: This header contains some C standard library functions used by anagram. + + Source: unknown + + Original name: anagram + + Changes: See ChangeLog.txt + + License: See anagram.c + +*/ + +#ifndef ANAGRAM_STRINGS_H +#define ANAGRAM_STRINGS_H + +void anagram_bzero( char *p, unsigned long len ); + +#endif diff --git a/all_pairs/source/audiobeam/README b/all_pairs/source/audiobeam/README new file mode 100644 index 0000000..e228eda --- /dev/null +++ b/all_pairs/source/audiobeam/README @@ -0,0 +1,86 @@ +Readme file for Oxygen beamforming source code distribution +----------------------------------------------------------- + +This is a very very beta distribution of beamforming source code from +MIT LCS. + +There is only one source file, main.c, and one header file, +main.h. You can compile everything using the Makefile included in the +distribution. + +The input to the program is a text file containing floating +point values for the signal read on each of the microphones. For n +microphones, each line of the text files represents a temporal sample +and should contain n floating point values separated by spaces, e.g.: + +-1.8569790e-004 -9.0919049e-004 3.6711283e-004 -1.0073081e-005 ... + +There are several modes of operation for the program: + +1. The most basic mode is to process the microphone data and to +calculate the output based on one beam focused on a particular point +in space. The coordinates for the microphones and the focus point are +specified inside main.c (eventually to be moved to a separate file). + +2. Far field search mode. This mode assumes a far-field source (which +means we have a planar wavefront) and a linear array, and sweeps over +180 degrees in the plane of the array. The microphone coordinates are +specified in main.c, and the NUM_ANGLES constant defines how many +angle values should be tested (a value of 180 means one beam per each +degree). The energy of the signal over a particular window +(ANGLE_ENERGY_WINDOW_SIZE) is computed for each beam. The direction +with maximum energy is considered the direction that the speech signal +is coming from, and is printed out by the program. + +3. Near-field hill climbing mode. This mode accepts a starting +coordinate and attempts to "hill-climb" through the space seeking the +maximum energy. Each of the x, y, and z coordinates are perturbed in +the positive and negative directions at each time interval +(GRID_ENERGY_WINDOW_SIZE) by a step size (GRID_STEP_SIZE). This +perturbation, along with the original coordinate, produces seven +coordinates to be tested. The direction with the maximum energy +replaces the current reference coordinate. For instance, if we have a +starting reference coordinate of (1,1,0) and our step size is 0.01, we +will evaluate the energy for the following seven beams: + +(1,1,0) +(0.99,1,0) +(1.01,1,0) +(1,0.99,0) +(1,1.01,0) +(1,1,-0.01) +(1,1,0.01) + +Now let's say the beam (1,1.01,0) has the maximum energy; then this +coordinate will replace the original reference coordinate of (1,1,0). + +For methods 2, and 3, we are not outputting anything to disk, we are +just printing the result. This is because we have just started to work +with these methods, and have not applied them in real systems. This +code is currently being ported to RAW. + +To get a list of parameters for the delay_and_sum executable that is +generated when the source is compiled, just type ./delay_and_sum . + +There is some sample data included with the program, in the data +directory. There is some data for a near-field and far-field +source. The README.txt file in each directory specifies the microphone +and source position. The data1 file, when processed with a beamformer +aligned in the proper direction should produce something like a sinc +function (see +http://ccrma-www.stanford.edu/~jos/Interpolation/sinc_function.html). + +The data2 file should produce an audio signal of a woman saying "the +simplest method". If the beamformer is aligned properly, the noise +should be reduced significantly over the source signal from only one +of the microphones (use print_datafile.pl to isolate one +microphone). You can convert the data file that the program produces +to wave files using sox. + + + + + +--------------------------------- +Eugene Weinstein +ecoder@mit.edu \ No newline at end of file diff --git a/all_pairs/source/audiobeam/audiobeam.c b/all_pairs/source/audiobeam/audiobeam.c new file mode 100644 index 0000000..ed5d656 --- /dev/null +++ b/all_pairs/source/audiobeam/audiobeam.c @@ -0,0 +1,594 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: audiobeam + + Author: Eugene Weinstein + + Function: Audio beam former + + Source: StreamIt + http://groups.csail.mit.edu/cag/streamit/ + + Changes: no functional changes + + License: see license.txt + +*/ + + +/* + Include section +*/ + +#include "../extra.h" +#include "audiobeamlibm.h" +#include "audiobeamlibmalloc.h" +#include "audiobeam.h" + +/* + Forward declaration of functions +*/ + +void audiobeam_init(); +int audiobeam_return(); +void audiobeam_main( void ); +//int main( void ); +void audiobeam_preprocess_delays( struct audiobeam_PreprocessedDelays + prep_delays[], float *delays ); +float *audiobeam_parse_line( float *float_arr, int num_mic ); +long int audiobeam_find_max_in_arr( float *arr, int size ); +long int audiobeam_find_min_in_arr( float *arr, int size ); +int audiobeam_wrapped_inc_offset( int i, int offset, int max_i ); +int audiobeam_wrapped_dec_offset( int i, int offset, int max_i ); +int audiobeam_wrapped_inc( int i, int max_i ); +int audiobeam_wrapped_dec( int i, int max_i ); +struct audiobeam_DataQueue *audiobeam_init_data_queue( int max_delay, + int num_mic ); +struct audiobeam_Delays *audiobeam_init_delays ( int num_angles, int num_mic ); +void audiobeam_calc_distances( float *source_location, + float audiobeam_mic_locations[15][3], + float *distances, + int num_mic ); +void audiobeam_calc_delays( float *distances, float *delays, int sound_speed, + int sampling_rate, int num_mic ); +void audiobeam_adjust_delays( float *delays, int num_mic ); +float *audiobeam_calc_weights_lr ( int num_mic ); +float *audiobeam_calc_weights_left_only ( int num_mic ); +float audiobeam_calculate_energy( float *samples, int num_samples ); +float audiobeam_do_beamforming( struct audiobeam_PreprocessedDelays + preprocessed_delays[], + float **sample_queue, + int queue_head, + long int max_delay, + int num_mic, + float *weights ); +int audiobeam_process_signal( struct audiobeam_Delays *delays, int num_mic, + float sampling_rate, float **beamform_results, + struct audiobeam_DataQueue *queue, + int num_beams, int window, float *weights ); +int audiobeam_calc_beamforming_result( struct audiobeam_Delays *delays, + float **beamform_results, + float *energies, + struct audiobeam_DataQueue *queue, + int num_beams, int window, + int hamming ); +void audiobeam_calc_single_pos( float source_location[3], + float audiobeam_mic_locations[15][3], + int hamming ); + + +/* + Declaration of global variables +*/ + +extern float audiobeam_input[5760]; +extern float audiobeam_mic_locations[15][3]; +extern float audiobeam_source_location[3]; +extern float audiobeam_origin_location[3]; +int audiobeam_input_pos; +int audiobeam_checksum; + + +/* + Initialization- and return-value-related functions +*/ + +void audiobeam_init() +{ + audiobeam_input_pos = 0; + audiobeam_checksum = 0; + + unsigned int i; + unsigned char *p; + volatile char bitmask = 0; + + /* + Apply volatile XOR-bitmask to entire input array. + */ + p = ( unsigned char * ) &audiobeam_input[ 0 ]; + _Pragma( "loopbound min 23040 max 23040" ) + for ( i = 0; i < sizeof( audiobeam_input ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &audiobeam_mic_locations[ 0 ]; + _Pragma( "loopbound min 180 max 180" ) + for ( i = 0; i < sizeof( audiobeam_mic_locations ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &audiobeam_source_location[ 0 ]; + _Pragma( "loopbound min 12 max 12" ) + for ( i = 0; i < sizeof( audiobeam_source_location ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &audiobeam_origin_location[ 0 ]; + _Pragma( "loopbound min 12 max 12" ) + for ( i = 0; i < sizeof( audiobeam_origin_location ); ++i, ++p ) + *p ^= bitmask; +} + + +int audiobeam_return() +{ + return ( audiobeam_checksum +1!= 0 ); +} + + +/* + Algorithm core functions +*/ + +void audiobeam_preprocess_delays( struct audiobeam_PreprocessedDelays + prep_delays[], float *delays ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < 15; i++ ) { + prep_delays[i].delay = delays[i]; + prep_delays[i].high = ( int ) audiobeam_ceil( delays[i] ); + prep_delays[i].low = ( int ) audiobeam_floor( delays[i] ); + prep_delays[i].offset = delays[i] - prep_delays[i].low; + } +} + + +float *audiobeam_parse_line( float *float_arr, int num_mic ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) + float_arr[i] = audiobeam_input[audiobeam_input_pos++]; + + return float_arr; +} + + +long int audiobeam_find_max_in_arr( float *arr, int size ) +{ + int i; + float max = 0; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < size; i++ ) { + if ( arr[i] > max ) + max = arr[i]; + } + + return audiobeam_ceil( max ); +} + + +long int audiobeam_find_min_in_arr( float *arr, int size ) +{ + int i; + float min = arr[0]; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < size; i++ ) { + if ( arr[i] < min ) + min = arr[i]; + } + + return audiobeam_floor( min ); +} + + +int audiobeam_wrapped_inc_offset( int i, int offset, int max_i ) +{ + if ( i + offset > max_i ) + return ( i + offset - max_i - 1 ); + else + return ( i + offset ); +} + + +int audiobeam_wrapped_dec_offset( int i, int offset, int max_i ) +{ + if ( i - offset < 0 ) + return ( max_i - ( offset - i ) + 1 ); + else + return ( i - offset ); +} + + +int audiobeam_wrapped_inc( int i, int max_i ) +{ + return audiobeam_wrapped_inc_offset( i, 1, max_i ); +} + + +int audiobeam_wrapped_dec( int i, int max_i ) +{ + return audiobeam_wrapped_dec_offset( i, 1, max_i ); +} + + +struct audiobeam_DataQueue *audiobeam_init_data_queue( int max_delay, + int num_mic ) +{ + int i, j; + + struct audiobeam_DataQueue *queue; + queue = ( struct audiobeam_DataQueue * ) audiobeam_malloc( sizeof( + struct audiobeam_DataQueue ) ); + queue->sample_queue = ( float ** ) audiobeam_malloc( ( max_delay + 1 ) + * sizeof( float * ) ); + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < ( max_delay + 1 ); i++ ) { + ( queue->sample_queue )[i] = ( float * ) audiobeam_malloc( num_mic + * sizeof( float ) ); + _Pragma( "loopbound min 15 max 15" ) + for ( j = 0; j < num_mic; j++ ) { + ( queue->sample_queue )[i][j] = 0.0; // Initialize values to 0 + } + } + + queue->head = 0; + queue->tail = 0; + queue->full = 0; + + return queue; +} + + +struct audiobeam_Delays *audiobeam_init_delays ( int num_angles, int num_mic ) +{ + struct audiobeam_Delays *delays; + int i; + + delays = ( struct audiobeam_Delays * ) audiobeam_malloc( sizeof( + struct audiobeam_Delays ) ); + + // Initialize the delays array + delays->delay_values = ( float ** ) audiobeam_malloc( num_angles + * sizeof( float * ) ); + + _Pragma( "loopbound min 1 max 1" ) + for ( i = 0; i < ( num_angles ); i++ ) { + delays->delay_values[i] = ( float * ) audiobeam_malloc( num_mic + * sizeof( float ) ); + } + + return delays; +} + +void audiobeam_calc_distances( float *source_location, + float audiobeam_mic_locations[15][3], + float *distances, + int num_mic ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) { + distances[i] = ( audiobeam_sqrt( ( audiobeam_mic_locations[i][0] + - source_location[0] ) * + ( audiobeam_mic_locations[i][0] + - source_location[0] ) + + ( audiobeam_mic_locations[i][1] + - source_location[1] ) * + ( audiobeam_mic_locations[i][1] + - source_location[1] ) + + ( audiobeam_mic_locations[i][2] + - source_location[2] ) * + ( audiobeam_mic_locations[i][2] + - source_location[2] ) ) ); + } +} + + +void audiobeam_calc_delays( float *distances, float *delays, int sound_speed, + int sampling_rate, int num_mic ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) + delays[i] = ( distances[i] / sound_speed ) * sampling_rate; +} + + +void audiobeam_adjust_delays( float *delays, int num_mic ) +{ + int i; + long int min_delay = audiobeam_find_min_in_arr ( delays, num_mic ) - 1; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) + delays[i] -= min_delay; +} + + +float *audiobeam_calc_weights_lr ( int num_mic ) +{ + float *weights = ( float * ) audiobeam_malloc( num_mic * sizeof( float ) ); + int index = 0; + int y, z; + + int half = num_mic / 4; + + _Pragma( "loopbound min 0 max 0" ) + for ( z = 1; z >= -1; z -= 2 ) { + _Pragma( "loopbound min 0 max 0" ) + for ( y = 0; y < half; y++ ) { + weights[index] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * y + / half ); + index++; + } + _Pragma( "loopbound min 0 max 0" ) + for ( y = 0; y < half; y++ ) { + weights[index] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * ( -y ) + / half ); + index++; + } + } + + return weights; +} + + +float *audiobeam_calc_weights_left_only ( int num_mic ) +{ + float *weights = ( float * ) audiobeam_malloc( num_mic * sizeof( float ) ); + int index = 0; + int y; + + int half = num_mic / 2; + + _Pragma( "loopbound min 15 max 15" ) + for ( y = -half; y <= half; y++ ) { + weights[index] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * y / half ); + index++; + } + + return weights; +} + + +float audiobeam_calculate_energy( float *samples, int num_samples ) +{ + int i; + float sum = 0.0; + + _Pragma( "loopbound min 0 max 0" ) + for ( i = 0; i < num_samples; i++ ) + sum += ( samples[i] * samples[i] ); + + return sum; +} + + +float audiobeam_do_beamforming( struct audiobeam_PreprocessedDelays + preprocessed_delays[], + float **sample_queue, + int queue_head, + long int max_delay, + int num_mic, + float *weights ) +{ + int i; + float sum = 0; + int delay_floor; + int delay_ceil; + int low_index; + int high_index; + float interpolated_value; + + // add up all the num_mic delayed samples + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) { + delay_floor = preprocessed_delays[i].low; + delay_ceil = preprocessed_delays[i].high; + + // Inline wrap around here + // Low index gets index of sample right before desired sample + low_index = queue_head + delay_floor; + if ( low_index > max_delay ) + low_index -= ( max_delay + 1 ); + + // High index gets index of sample right after desired sample + high_index = queue_head + delay_ceil; + if ( high_index > max_delay ) + high_index -= ( max_delay + 1 ); + + // i gives the value of the microphone we want. However, since + // the array only has microphones first_mic to last_mic, we + // need to offset our index by first_mic + + interpolated_value = ( ( ( sample_queue[high_index][i] - + sample_queue[low_index][i] ) + * ( preprocessed_delays[i].offset ) ) + + sample_queue[low_index][i] ); + + // If we have microphone weights, multiply the value by the weight + if ( weights != 0 ) + sum += ( interpolated_value * weights[i] ); + else + sum += interpolated_value; + } + + return sum; + +} + + +int audiobeam_process_signal( struct audiobeam_Delays *delays, int num_mic, + float sampling_rate, float **beamform_results, + struct audiobeam_DataQueue *queue, + int num_beams, int window, float *weights ) +{ + int i, j; + float time_index = 0; + float time_index_inc = ( 1.0 / sampling_rate ); + + float value; + + int done = 0; + + struct audiobeam_PreprocessedDelays preprocessed_delays[15]; + + audiobeam_preprocess_delays( preprocessed_delays, delays->delay_values[0] ); + + _Pragma( "loopbound min 13 max 13" ) + for ( i = 0; i < delays->max_delay - 1; i++ ) { + if ( audiobeam_input_pos < 5760 ) + audiobeam_parse_line( ( queue->sample_queue )[queue->head], 15 ); + else + return -1; + queue->head = audiobeam_wrapped_inc( queue->head, delays->max_delay ); + } + _Pragma( "loopbound min 371 max 371" ) + for ( i = 0; ( i < window ) || ( window < 0 ) ; i++ ) { + if ( audiobeam_input_pos < 5760 ) + audiobeam_parse_line( ( queue->sample_queue )[queue->head], 15 ); + else { + done = 1; + break; + } + + _Pragma( "loopbound min 1 max 1" ) + for ( j = 0; j < num_beams; j++ ) { + value = audiobeam_do_beamforming( preprocessed_delays, + ( queue->sample_queue ), + audiobeam_wrapped_inc( queue->head, + delays->max_delay ), + delays->max_delay, num_mic, weights ); + + + value = value / num_mic; + + if ( beamform_results != 0 ) + beamform_results[j][i] = value; + } + + queue->tail = queue->head; + queue->head = audiobeam_wrapped_inc( queue->head, delays->max_delay ); + + time_index += time_index_inc; + } + + return ( done ); +} + + +int audiobeam_calc_beamforming_result( struct audiobeam_Delays *delays, + float **beamform_results, + float *energies, + struct audiobeam_DataQueue *queue, + int num_beams, int window, + int hamming ) +{ + int i; + int done; + float *weights = 0; + + if ( hamming ) { + if ( ( 15 % 2 ) == 1 ) + weights = audiobeam_calc_weights_left_only( 15 ); + else + weights = audiobeam_calc_weights_lr( 15 ); + } + + done = audiobeam_process_signal( delays, 15, 16000, + beamform_results, + queue, num_beams, window, weights ); + + if ( beamform_results != 0 ) { + _Pragma( "loopbound min 1 max 1" ) + for ( i = 0; i < num_beams; i++ ) + energies[i] = audiobeam_calculate_energy( beamform_results[i], window ); + } + return done; +} + + +void audiobeam_calc_single_pos( float source_location[3], + float audiobeam_mic_locations[15][3], + int hamming ) +{ + float mic_distances[15]; + struct audiobeam_Delays *delays = audiobeam_init_delays( 1, 15 ); + struct audiobeam_DataQueue *queue; + + float **beamform_results; + float *energies; + + beamform_results = ( float ** ) audiobeam_malloc( 1 * sizeof( float * ) ); + beamform_results[0] = ( float * ) audiobeam_malloc( 384 * sizeof( float ) ); + energies = ( float * ) audiobeam_malloc( 1 * sizeof( float * ) ); + + // Calculate distances from source to each of mics + audiobeam_calc_distances( source_location, audiobeam_mic_locations, + mic_distances, 15 ); + + audiobeam_calc_delays( mic_distances, + delays->delay_values[0], + 342, 16000, 15 ); + + audiobeam_adjust_delays( delays->delay_values[0], 15 ); + + delays->max_delay = audiobeam_find_max_in_arr ( delays->delay_values[0], 15 ); + + queue = audiobeam_init_data_queue( delays->max_delay, 15 ); + + audiobeam_calc_beamforming_result( delays, beamform_results, + energies, queue, 1, -1, hamming ); + + audiobeam_checksum += beamform_results[0][0] * 1000; +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) audiobeam_main( void ) +{ + char hamming = 1; + audiobeam_calc_single_pos( audiobeam_source_location, + audiobeam_mic_locations, + hamming ); +} + + +int main( int argc, char **argv ) +{ + //SET_UP + int jobsComplete; + int maxJobs=100; + for (jobsComplete=-1; jobsComplete 0 ) { + z = x - audiobeam_pio2_1; + if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { + y[0] = z - audiobeam_pio2_1t; + y[1] = ( z - y[0] ) - audiobeam_pio2_1t; + } else { + z -= audiobeam_pio2_2; + y[0] = z - audiobeam_pio2_2t; + y[1] = ( z - y[0] ) - audiobeam_pio2_2t; + } + return 1; + } else { + z = x + audiobeam_pio2_1; + if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { + y[0] = z + audiobeam_pio2_1t; + y[1] = ( z - y[0] ) + audiobeam_pio2_1t; + } else { + z += audiobeam_pio2_2; + y[0] = z + audiobeam_pio2_2t; + y[1] = ( z - y[0] ) + audiobeam_pio2_2t; + } + return -1; + } + } + if ( ix <= 0x43490f80 ) { + t = audiobeam_fabsf( x ); + n = ( int ) ( t * audiobeam_invpio2 + audiobeam_half ); + fn = ( float )n; + r = t - fn * audiobeam_pio2_1; + w = fn * audiobeam_pio2_1t; + if ( n < 32 && ( int )( ix & 0xffffff00 ) != audiobeam_npio2_hw[n - 1] ) + y[0] = r - w; + else { + unsigned int high; + j = ix >> 23; + y[0] = r - w; + AUDIOBEAM_GET_FLOAT_WORD( high, y[0] ); + i = j - ( ( high >> 23 ) & 0xff ); + if ( i > 8 ) { + t = r; + w = fn * audiobeam_pio2_2; + r = t - w; + w = fn * audiobeam_pio2_2t - ( ( t - r ) - w ); + y[0] = r - w; + AUDIOBEAM_GET_FLOAT_WORD( high, y[0] ); + i = j - ( ( high >> 23 ) & 0xff ); + if ( i > 25 ) { + t = r; + w = fn * audiobeam_pio2_3; + r = t - w; + w = fn * audiobeam_pio2_3t - ( ( t - r ) - w ); + y[0] = r - w; + } + } + } + y[1] = ( r - y[0] ) - w; + if ( hx < 0 ) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } else return n; + } + if ( ix >= 0x7f800000 ) { + y[0] = y[1] = x - x; + return 0; + } + + return n; +} + + +float audiobeam___kernel_cosf( float x, float y ) +{ + float a, hz, z, r, qx; + int ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + ix &= 0x7fffffff; + if ( ix < 0x32000000 ) { + if ( ( ( int )x ) == 0 ) return audiobeam_one; + } + z = x * x; + r = z * ( audiobeam_C1 + z * ( audiobeam_C2 + z * ( audiobeam_C3 + z * + ( audiobeam_C4 + z * + ( audiobeam_C5 + z * audiobeam_C6 ) ) ) ) ); + if ( ix < 0x3e99999a ) + return audiobeam_one - ( ( float )0.5f * z - ( z * r - x * y ) ); + else { + if ( ix > 0x3f480000 ) + qx = ( float )0.28125f; + else + AUDIOBEAM_SET_FLOAT_WORD( qx, ix - 0x01000000 ); + hz = ( float )0.5f * z - qx; + a = audiobeam_one - qx; + return a - ( hz - ( z * r - x * y ) ); + } +} + + +float audiobeam___kernel_sinf( float x, float y, int iy ) +{ + float z, r, v; + int ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + ix &= 0x7fffffff; + if ( ix < 0x32000000 ) { + if ( ( int )x == 0 ) return x; + } + z = x * x; + v = z * x; + r = audiobeam_S2 + z * ( audiobeam_S3 + z * ( audiobeam_S4 + z * ( audiobeam_S5 + z * audiobeam_S6 ) ) ); + if ( iy == 0 ) return x + v * ( audiobeam_S1 + z * r ); + else return x - ( ( z * ( audiobeam_half * y - v * r ) - y ) - v * audiobeam_S1 ); +} + + +float audiobeam___copysignf( float x, float y ) +{ + unsigned int ix, iy; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + AUDIOBEAM_GET_FLOAT_WORD( iy, y ); + AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x7fffffff ) | ( iy & 0x80000000 ) ); + return x; +} + + +float audiobeam___cosf( float x ) +{ + float y[2], z = 0.0f; + int n, ix; + + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + + ix &= 0x7fffffff; + if ( ix <= 0x3f490fd8 ) return audiobeam___kernel_cosf( x, z ); + + else + if ( ix >= 0x7f800000 ) return x - x; + + else { + y[0] = 0.0; + y[1] = 0.0; + n = audiobeam___ieee754_rem_pio2f( x, y ); + switch ( n & 3 ) { + case 0: + return audiobeam___kernel_cosf( y[0], y[1] ); + case 1: + return -audiobeam___kernel_sinf( y[0], y[1], 1 ); + case 2: + return -audiobeam___kernel_cosf( y[0], y[1] ); + default: + return audiobeam___kernel_sinf( y[0], y[1], 1 ); + } + } +} + + +float audiobeam___fabsf( float x ) +{ + unsigned int ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + AUDIOBEAM_SET_FLOAT_WORD( x, ix & 0x7fffffff ); + return x; +} + + +float audiobeam___floorf( float x ) +{ + int i0, j0; + unsigned int i; + AUDIOBEAM_GET_FLOAT_WORD( i0, x ); + j0 = ( ( i0 >> 23 ) & 0xff ) - 0x7f; + if ( j0 < 23 ) { + if ( j0 < 0 ) { + if ( audiobeam_huge + x > ( float )0.0f ) { + if ( i0 >= 0 ) + i0 = 0; + else + if ( ( i0 & 0x7fffffff ) != 0 ) + i0 = 0xbf800000; + } + } else { + i = ( 0x007fffff ) >> j0; + if ( ( i0 & i ) == 0 ) return x; + if ( audiobeam_huge + x > ( float )0.0f ) { + if ( i0 < 0 ) i0 += ( 0x00800000 ) >> j0; + i0 &= ( ~i ); + } + } + } else { + if ( j0 == 0x80 ) return x + x; + else return x; + } + AUDIOBEAM_SET_FLOAT_WORD( x, i0 ); + return x; +} + + +int audiobeam___isinff ( float x ) +{ + int ix, t; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + t = ix & 0x7fffffff; + t ^= 0x7f800000; + t |= -t; + return ~( t >> 31 ) & ( ix >> 30 ); +} + + +float audiobeam___scalbnf ( float x, int n ) +{ + int k, ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + k = ( ix & 0x7f800000 ) >> 23; + if ( k == 0 ) { + if ( ( ix & 0x7fffffff ) == 0 ) return x; + x *= audiobeam_two25; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + k = ( ( ix & 0x7f800000 ) >> 23 ) - 25; + } + if ( k == 0xff ) return x + x; + k = k + n; + if ( n > 50000 || k > 0xfe ) + return audiobeam_huge * audiobeam___copysignf( audiobeam_huge, + x ); + if ( n < -50000 ) + return audiobeam_tiny * audiobeam___copysignf( audiobeam_tiny, + x ); + if ( k > 0 ) { + AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) ); + return x; + } + if ( k <= -25 ) + return audiobeam_tiny * audiobeam___copysignf( audiobeam_tiny, + x ); + k += 25; + AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) ); + return x * audiobeam_twom25; +} + + +float audiobeam___ceilf( float x ) +{ + int i0, j0; + unsigned int i; + + AUDIOBEAM_GET_FLOAT_WORD( i0, x ); + j0 = ( ( i0 >> 23 ) & 0xff ) - 0x7f; + if ( j0 < 23 ) { + if ( j0 < 0 ) { + if ( audiobeam_huge + x > ( float )0.0 ) { + if ( i0 < 0 ) + i0 = 0x80000000; + else + if ( i0 != 0 ) + i0 = 0x3f800000; + } + } else { + i = ( 0x007fffff ) >> j0; + if ( ( i0 & i ) == 0 ) return x; + if ( audiobeam_huge + x > ( float )0.0 ) { + if ( i0 > 0 ) i0 += ( 0x00800000 ) >> j0; + i0 &= ( ~i ); + } + } + } else { + if ( j0 == 0x80 ) return x + x; + else return x; + } + AUDIOBEAM_SET_FLOAT_WORD( x, i0 ); + return x; +} + + +float audiobeam___ieee754_sqrtf( float x ) +{ + float z; + int sign = ( int )0x80000000; + int ix, s, q, m, t, i; + unsigned int r; + + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + + if ( ( ix & 0x7f800000 ) == 0x7f800000 ) + return x * x + x; + if ( ix <= 0 ) { + if ( ( ix & ( ~sign ) ) == 0 ) return x; + else + if ( ix < 0 ) + return ( x - x ) / ( x - x ); + } + m = ( ix >> 23 ); + if ( m == 0 ) { + _Pragma( "loopbound min 0 max 0" ) + for ( i = 0; ( ix & 0x00800000 ) == 0; i++ ) + ix <<= 1; + m -= i - 1; + } + m -= 127; + ix = ( ix & 0x007fffff ) | 0x00800000; + if ( m & 1 ) + ix += ix; + m >>= 1; + + ix += ix; + q = s = 0; + r = 0x01000000; + + _Pragma( "loopbound min 25 max 25" ) + while ( r != 0 ) { + t = s + r; + if ( t <= ix ) { + s = t + r; + ix -= t; + q += r; + } + ix += ix; + r >>= 1; + } + + if ( ix != 0 ) { + z = audiobeam_one - audiobeam_tiny; + if ( z >= audiobeam_one ) { + z = audiobeam_one + audiobeam_tiny; + if ( z > audiobeam_one ) + q += 2; + else + q += ( q & 1 ); + } + } + ix = ( q >> 1 ) + 0x3f000000; + ix += ( m << 23 ); + AUDIOBEAM_SET_FLOAT_WORD( z, ix ); + return z; +} diff --git a/all_pairs/source/audiobeam/audiobeamlibm.h b/all_pairs/source/audiobeam/audiobeamlibm.h new file mode 100644 index 0000000..b06b563 --- /dev/null +++ b/all_pairs/source/audiobeam/audiobeamlibm.h @@ -0,0 +1,59 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: quicksortlibm.c + + Author: Ian Lance Taylor + + Function: IEEE754 software library routines. + + Source: Sun Microsystems and Cygnus + + Original name: Unknown + + Changes: No major functional changes. + + License: See audiobeamlibm.c + +*/ + +#ifndef AUDIOBEAM_LIBM +#define AUDIOBEAM_LIBM + +#define audiobeam_M_PI 3.14159265358979323846 + +static const float +audiobeam_one = 1.0f, +audiobeam_tiny = 1.0e-30f, +audiobeam_half = 5.0000000000e-01, /* 0x3f000000 */ +audiobeam_huge = 1.0e30, +audiobeam_two8 = 2.5600000000e+02, /* 0x43800000 */ +audiobeam_twon8 = 3.9062500000e-03, /* 0x3b800000 */ +audiobeam_zero = 0.0; + +#define audiobeam_cos audiobeam___cosf +#define audiobeam_fabs audiobeam___fabsf +#define audiobeam_fabsf audiobeam___fabsf +#define audiobeam_isinf audiobeam___isinff +#define audiobeam_sqrt audiobeam___ieee754_sqrtf +#define audiobeam_ceil audiobeam___ceilf +#define audiobeam_floor audiobeam___floorf + +float audiobeam___copysignf( float x, float y ); +float audiobeam___cosf( float x ); +float audiobeam___fabsf( float x ); +float audiobeam___floorf( float x ); +int audiobeam___ieee754_rem_pio2f( float x, float *y ); +float audiobeam___ieee754_sqrtf( float x ); +int audiobeam___isinff ( float x ); +float audiobeam___kernel_cosf( float x, float y ); +float audiobeam___kernel_sinf( float x, float y, int iy ); +int audiobeam___kernel_rem_pio2f( float *x, float *y, int e0, int nx, + int prec, const int *ipio2 ); +float audiobeam___scalbnf ( float x, int n ); +float audiobeam___ceilf( float x ); +float audiobeam___floorf( float x ); + +#endif // AUDIOBEAM_LIBM diff --git a/all_pairs/source/audiobeam/audiobeamlibmalloc.c b/all_pairs/source/audiobeam/audiobeamlibmalloc.c new file mode 100644 index 0000000..50c3073 --- /dev/null +++ b/all_pairs/source/audiobeam/audiobeamlibmalloc.c @@ -0,0 +1,14 @@ +#include "audiobeamlibmalloc.h" + +#define AUDIOBEAM_HEAP_SIZE 10000 + +static char audiobeam_simulated_heap[AUDIOBEAM_HEAP_SIZE]; +static unsigned int audiobeam_freeHeapPos; + +void *audiobeam_malloc( unsigned int numberOfBytes ) +{ + void *currentPos = ( void * )&audiobeam_simulated_heap[ audiobeam_freeHeapPos ]; + /* Get a 4-byte address for alignment purposes */ + audiobeam_freeHeapPos += ( ( numberOfBytes + 4 ) & ( unsigned int )0xfffffffc ); + return currentPos; +} \ No newline at end of file diff --git a/all_pairs/source/audiobeam/audiobeamlibmalloc.h b/all_pairs/source/audiobeam/audiobeamlibmalloc.h new file mode 100644 index 0000000..eccbdb9 --- /dev/null +++ b/all_pairs/source/audiobeam/audiobeamlibmalloc.h @@ -0,0 +1,27 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: audiobeamlibmalloc.c + + Author: unkown + + Function: Memory allocation. + + Source: Sun Microsystems and Cygnus + + Original name: Unknown + + Changes: No major functional changes. + + License: see license.txt + +*/ + +#ifndef AUDIOBEAM_MALLOC_H +#define AUDIOBEAM_MALLOC_H + +void *audiobeam_malloc( unsigned int numberOfBytes ); + +#endif diff --git a/all_pairs/source/audiobeam/audiobeamlibmath.h b/all_pairs/source/audiobeam/audiobeamlibmath.h new file mode 100644 index 0000000..77bda0f --- /dev/null +++ b/all_pairs/source/audiobeam/audiobeamlibmath.h @@ -0,0 +1,69 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: audiobeamlibmath.h + + Author: Unknown + + Function: IEEE754 software library routines. + + Source: Sun Microsystems + + Original name: math_private.h + + Changes: No major functional changes. + + License: See the terms below. + +*/ + + +/* + ==================================================== + Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + + Developed at SunPro, a Sun Microsystems, Inc. business. + Permission to use, copy, modify, and distribute this + software is freely granted, provided that this notice + is preserved. + ==================================================== +*/ + +/* + from: @(#)fdlibm.h 5.1 93/09/24 +*/ + +#ifndef AUDIOBEAM_MATH_PRIVATE_H_ +#define AUDIOBEAM_MATH_PRIVATE_H_ + +#include "audiobeamlibm.h" + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union { + float value; + unsigned int word; +} audiobeam_ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define AUDIOBEAM_GET_FLOAT_WORD(i,d) \ +{ \ + audiobeam_ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} + +/* Set a float from a 32 bit int. */ + +#define AUDIOBEAM_SET_FLOAT_WORD(d,i) \ +{ \ + audiobeam_ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/all_pairs/source/audiobeam/changeLog.txt b/all_pairs/source/audiobeam/changeLog.txt new file mode 100644 index 0000000..b9b8933 --- /dev/null +++ b/all_pairs/source/audiobeam/changeLog.txt @@ -0,0 +1,36 @@ +File: audiobeam.c +Original provenience: StreamIt + http://groups.csail.mit.edu/cag/streamit/ + +2015-12-29: +- Removed original header comment, replaced by TACLeBench header. +- Renamed libraryfiles according to TACLeBench naming scheme. +- Removed all preprocessor macros, integrated them directly in the source code. +- Added prefix "audiobeam_" to all global symbols. +- Added explicit forward declarations of functions. +- Added an empty init function +- Added preprocessor command to determine if 32 or 64 bit in audiobeamlibmalloc.h +- Added new function audiobeam_return producing a checksum as return value. +- Added new function audiobeam_main according to TACLeBench guidelines. + audiobeam_main is annotated as entry-point for timing analysis. +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: bs_) followed by lowercase letter (e.g., bs_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur \ No newline at end of file diff --git a/all_pairs/source/audiobeam/license.txt b/all_pairs/source/audiobeam/license.txt new file mode 100644 index 0000000..7029925 --- /dev/null +++ b/all_pairs/source/audiobeam/license.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/all_pairs/source/cjpeg_transupp/ChangeLog.txt b/all_pairs/source/cjpeg_transupp/ChangeLog.txt new file mode 100644 index 0000000..df4383c --- /dev/null +++ b/all_pairs/source/cjpeg_transupp/ChangeLog.txt @@ -0,0 +1,36 @@ +File: cjpeg_transupp.c +Original provenience: MediaBench II benchmark suite, + http://euler.slu.edu/~fritts/mediabench (mirror) + +2015-11-03: +- Removed original header comment, replaced by TACLeBench header. +- Removed unnecessary preprocessor macros. +- Removed unnecessary code parts, simplified header files and include + relationships. +- Added prefix "cjpeg_transupp" to all global symbols. +- Added explicit forward declarations of functions. +- Replaced initialization code by TACLeBench-compliant initialization code. +- Added new function cjpeg_transupp_return producing a checksum as return value. +- Added new function cjpeg_transupp_main according to TACLeBench guidelines. + cjpeg_transupp_main is annotated as entry-point for timing analysis. +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: bs_) followed by lowercase letter (e.g., bs_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur diff --git a/all_pairs/source/cjpeg_transupp/README b/all_pairs/source/cjpeg_transupp/README new file mode 100644 index 0000000..8dba954 --- /dev/null +++ b/all_pairs/source/cjpeg_transupp/README @@ -0,0 +1,417 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 6a of 7-Feb-96 +================================= + +This distribution contains the sixth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +Serious users of this software (particularly those incorporating it into +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to +our electronic mailing list. Mailing list members are notified of updates +and have a chance to participate in technical discussions, etc. + +This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim +Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi, +Ge' Weijers, and other members of the Independent JPEG Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +RELATED SOFTWARE Other stuff you should get. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.doc How to configure and install the IJG software. + usage.doc Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.doc). + wizard.doc Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.doc How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.doc Overview of the JPEG library's internal structure. + filelist.doc Road map of IJG files. + coderules.doc Coding style rules --- please read if you contribute code. + +Please read at least the files install.doc and usage.doc. Useful information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image compression and +decompression. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. JPEG is intended for compressing +"real-world" scenes; line drawings, cartoons and other non-realistic images +are not its strong suit. JPEG is lossy, meaning that the output image is not +exactly identical to the input image. Hence you must not use JPEG if you +have to have identical output bits. However, on typical photographic images, +very good compression levels can be obtained with no visible change, and +remarkably high compression levels are possible if you can tolerate a +low-quality image. For more details, see the references, or just experiment +with various compression settings. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +For legal reasons, we are not distributing code for the arithmetic-coding +variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting +the hierarchical or lossless processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. We have also included +"jpegtran", a utility for lossless transcoding between different JPEG +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for +inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + +Lossless image transformation routines. These routines work on DCT coefficient +arrays and thus do not require any lossy decompression or recompression of the +image. Thanks to Guido Vollbeding for the initial design and code of this +feature. + +Horizontal flipping is done in-place, using a single top-to-bottom pass through +the virtual source array. It will thus be much the fastest option for images +larger than main memory. + +The other routines require a set of destination virtual arrays, so they need +twice as much memory as jpegtran normally does. The destination arrays are +always written in normal scan order (top to bottom) because the virtual array +manager expects this. The source arrays will be scanned in the corresponding +order, which means multiple passes through the source arrays for most of the +transforms. That could result in much thrashing if the image is larger than main +memory. + +Some notes about the operating environment of the individual transform routines: +1. Both the source and destination virtual arrays are allocated from the source + JPEG object, and therefore should be manipulated by calling the source's + memory manager. +2. The destination's component count should be used. It may be smaller than the + source's when forcing to grayscale. +3. Likewise the destination's sampling factors should be used. When forcing to + grayscale the destination's sampling factors will be all 1, and we may as + well take that as the effective iMCU size. +4. When "trim" is in effect, the destination's dimensions will be the trimmed + values but the source's will be untrimmed. +5. All the routines assume that the source and destination buffers are padded + out to a full iMCU boundary. This is true, although for the source buffer it + is an undocumented property of jdcoefct.c. +Notes 2,3,4 boil down to this: generally we should use the destination's +dimensions and ignore the source's. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-1996, Thomas G. Lane. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The configuration script "configure" was produced with GNU Autoconf. It +is copyright by the Free Software Foundation but is freely distributable. + +It appears that the arithmetic coding option of the JPEG spec is covered by +patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot +legally be used without obtaining one or more licenses. For this reason, +support for arithmetic coding has been removed from the free JPEG software. +(Since arithmetic coding provides only a marginal gain over the unpatented +Huffman mode, it is unlikely that very many implementations will support it.) +So far as we are aware, there are no patent restrictions on the remaining +code. + +WARNING: Unisys has begun to enforce their patent on LZW compression against +GIF encoders and decoders. You will need a license from Unisys to use the +included rdgif.c or wrgif.c files in a commercial or shareware application. +At this time, Unisys is not enforcing their patent against freeware, so +distribution of this package remains legal. However, we intend to remove +GIF support from the IJG package as soon as a suitable replacement format +becomes reasonably popular. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." + + +REFERENCES +========== + +We highly recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article +is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and +IEEE, and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood +City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and +example C code for a multitude of compression methods including JPEG. It is +an excellent source if you are comfortable reading C code but don't know much +about data compression in general. The book's JPEG sample code is far from +industrial-strength, but when you are ready to look at a full implementation, +you've got one here... + +The best full description of JPEG is the textbook "JPEG Still Image Data +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. +The book includes the complete text of the ISO JPEG standards (DIS 10918-1 +and draft DIS 10918-2). This is by far the most complete exposition of JPEG +in existence, and we highly recommend it. + +The JPEG standard itself is not available electronically; you must order a +paper copy through ISO or ITU. (Unless you feel a need to own a certified +official copy, we recommend buying the Pennebaker and Mitchell book instead; +it's much cheaper and includes a great deal of useful explanatory material.) +In the USA, copies of the standard may be ordered from ANSI Sales at (212) +642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI +doesn't take credit card orders, but Global does.) It's not cheap: as of +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% +shipping/handling. The standard is divided into two parts, Part 1 being the +actual specification, while Part 2 covers compliance testing methods. Part 1 +is titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. + +Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO +document. Part 3 is undergoing ISO balloting and is expected to be approved +by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T +T.84. IJG currently does not support any Part 3 extensions. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. A copy of the JFIF spec is available from: + Literature Department + C-Cube Microsystems, Inc. + 1778 McCarthy Blvd. + Milpitas, CA 95035 + phone (408) 944-6300, fax (408) 944-6314 +A PostScript version of this document is available at ftp.uu.net, file +graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube +mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" +to the server to obtain the JFIF document; send the message "help" if you have +trouble. + +The TIFF 6.0 file format specification can be obtained by FTP from sgi.com +(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed +copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from sgi.com or +from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of +the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. libtiff is available +from sgi.com:/graphics/tiff/. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is ftp.uu.net (Internet +address 192.48.96.9). The most recent released version can always be found +there in directory graphics/jpeg. This particular version will be archived +as graphics/jpeg/jpegsrc.v6a.tar.gz. If you are on the Internet, you +can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't +have FTP access, UUNET's archives are also available via UUCP; contact +help@uunet.uu.net for information on retrieving files that way. + +Numerous Internet sites maintain copies of the UUNET files. However, only +ftp.uu.net is guaranteed to have the latest official version. + +You can also obtain this software in DOS-compatible "zip" archive format from +the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe +in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools". +Again, these versions may sometimes lag behind the ftp.uu.net release. + +The JPEG FAQ (Frequently Asked Questions) article is a useful source of +general information about JPEG. It is updated constantly and therefore is +not included in this distribution. The FAQ is posted every two weeks to +Usenet newsgroups comp.graphics.misc, news.answers, and other groups. +You can always obtain the latest version from the news.answers archive at +rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and +.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +RELATED SOFTWARE +================ + +Numerous viewing and image manipulation programs now support JPEG. (Quite a +few of them use this library to do so.) The JPEG FAQ described above lists +some of the more popular free and shareware viewers, and tells where to +obtain them on Internet. + +If you are on a Unix machine, we highly recommend Jef Poskanzer's free +PBMPLUS image software, which provides many useful operations on PPM-format +image files. In particular, it can convert PPM images to and from a wide +range of other formats. You can obtain this package by FTP from ftp.x.org +(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also +a newer update of this package called NETPBM, available from +wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/. +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software +is; you are likely to have difficulty making it work on any non-Unix machine. + +A different free JPEG implementation, written by the PVRG group at Stanford, +is available from havefun.stanford.edu in directory pub/jpeg. This program +is designed for research and experimentation rather than production use; +it is slower, harder to use, and less portable than the IJG code, but it +is easier to read and modify. Also, the PVRG code supports lossless JPEG, +which we do not. + + +FILE FORMAT WARS +================ + +Some JPEG programs produce files that are not compatible with our library. +The root of the problem is that the ISO JPEG committee failed to specify a +concrete file format. Some vendors "filled in the blanks" on their own, +creating proprietary formats that no one else could read. (For example, none +of the early commercial JPEG implementations for the Macintosh were able to +exchange compressed files.) + +The file format we have adopted is called JFIF (see REFERENCES). This format +has been agreed to by a number of major commercial JPEG vendors, and it has +become the de facto standard. JFIF is a minimal or "low end" representation. +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF +Technical Note #2) for "high end" applications that need to record a lot of +additional data about an image. TIFF/JPEG is fairly new and not yet widely +supported, unfortunately. + +The upcoming JPEG Part 3 standard defines a file format called SPIFF. +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should +be able to read the most common variant of SPIFF. SPIFF has some technical +advantages over JFIF, but its major claim to fame is simply that it is an +official standard rather than an informal one. At this point it is unclear +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto +standard. IJG intends to support SPIFF once the standard is frozen, but we +have not decided whether it should become our default output format or not. +(In any case, our decoder will remain capable of reading JFIF indefinitely.) + +Various proprietary file formats incorporating JPEG compression also exist. +We have little or no sympathy for the existence of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, open format standards for JPEG files. Don't +use a proprietary file format! + + +TO DO +===== + +In future versions, we are considering supporting some of the upcoming JPEG +Part 3 extensions --- principally, variable quantization and the SPIFF file +format. + +Tuning the software for better behavior at low quality/high compression +settings is also of interest. The current method for scaling the +quantization tables is known not to be very good at low Q values. + +As always, speeding things up is high on our priority list. + +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/all_pairs/source/cjpeg_transupp/cjpeg_transupp.c b/all_pairs/source/cjpeg_transupp/cjpeg_transupp.c new file mode 100644 index 0000000..e77d15b --- /dev/null +++ b/all_pairs/source/cjpeg_transupp/cjpeg_transupp.c @@ -0,0 +1,718 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: cjpeg_transupp + + Author: Thomas G. Lane + + Function: This file contains image transformation routines and other utility + code used by the jpegtran sample application. These are NOT part of the core + JPEG library. But we keep these routines separate from jpegtran.c to ease + the task of maintaining jpegtran-like programs that have other user + interfaces. + + Source: MediaBench II + http://euler.slu.edu/~fritts/mediabench (mirror) + + Original name: cjpeg + + Changes: No major functional changes. + + License: See the accompanying README file. + +*/ + + +/* + Include section +*/ + +#include "../extra.h" +#include "jpeglib.h" + + +/* + Forward declaration of functions +*/ + +void cjpeg_transupp_initSeed( void ); +signed char cjpeg_transupp_randomInteger( void ); +void cjpeg_transupp_init( void ); +int cjpeg_transupp_return( void ); +void cjpeg_transupp_do_flip_v( j_compress_ptr ); +void cjpeg_transupp_do_rot_90( j_compress_ptr ); +void cjpeg_transupp_do_rot_180( j_compress_ptr ); +void cjpeg_transupp_do_rot_270( j_compress_ptr ); +void cjpeg_transupp_do_transverse( j_compress_ptr ); +void cjpeg_transupp_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +volatile int cjpeg_transupp_seed; + +signed char cjpeg_transupp_input[ 256 ]; +signed char cjpeg_transupp_input2[ 80 ]; +signed char cjpeg_transupp_input3[ 65 ]; +signed char cjpeg_transupp_input3_2[ 65 ]; +signed char cjpeg_transupp_input4[ 64 ]; +signed char cjpeg_transupp_input5[ 65 ]; +signed char cjpeg_transupp_input5_2[ 65 ]; + +/* Output arrays replace writing of results into a file. */ +signed char cjpeg_transupp_output_data[ 512 ]; +signed char cjpeg_transupp_output_data2[ 512 ]; +signed char cjpeg_transupp_output_data3[ 512 ]; +signed char cjpeg_transupp_output_data4[ 512 ]; +signed char cjpeg_transupp_output_data5[ 512 ]; + +struct jpeg_compress_struct cjpeg_transupp_dstinfo; + + +/* + Initialization- and return-value-related functions +*/ + +void cjpeg_transupp_initSeed( void ) +{ + cjpeg_transupp_seed = 0; +} + + +/* + cjpeg_transupp_RandomInteger generates random integers between -128 and 127. +*/ +signed char cjpeg_transupp_randomInteger( void ) +{ + cjpeg_transupp_seed = ( ( ( cjpeg_transupp_seed * 133 ) + 81 ) % 256 ) - 128; + return( cjpeg_transupp_seed ); +} + + +void cjpeg_transupp_init( void ) +{ + register int i; + + + cjpeg_transupp_dstinfo.max_h_samp_factor = 2; + cjpeg_transupp_dstinfo.max_v_samp_factor = 2; + cjpeg_transupp_dstinfo.num_components = 3; + + cjpeg_transupp_initSeed(); + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) + cjpeg_transupp_input[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 80 max 80" ) + for ( i = 0; i < 80; i++ ) + cjpeg_transupp_input2[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input3[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input3_2[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < 64; i++ ) + cjpeg_transupp_input4[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input5[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input5_2[ i ] = cjpeg_transupp_randomInteger(); +} + + +int cjpeg_transupp_return( void ) +{ + int checksum = 0; + unsigned int i; + + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data2[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data3[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data4[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data5[ i ]; + + return( checksum ); +} + + +/* + Algorithm core functions +*/ + +/* + Vertical flip +*/ +void cjpeg_transupp_do_flip_v( j_compress_ptr dstinfo ) +{ + unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + + /* + We output into a separate array because we can't touch different rows of the + source virtual array simultaneously. Otherwise, this is a pretty + straightforward analog of horizontal flip. + Within a DCT block, vertical mirroring is done by changing the signs of + odd-numbered rows. + Partial iMCUs at the bottom edge are copied verbatim. + */ + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 19; + unsigned int compptr_width_in_blocks = 29; + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; + ci++, compptr_v_samp_factor = 1, compptr_width_in_blocks = 15 ) { + comp_height = MCU_rows * compptr_v_samp_factor; + + compptr_height_in_blocks = 10; + _Pragma( "loopbound min 2 max 10" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + + _Pragma( "loopbound min 1 max 8" ) + for ( offset_y = 0; offset_y < compptr_v_samp_factor; offset_y++ ) { + if ( dst_blk_y < comp_height ) { + + /* Row is within the mirrorable area. */ + _Pragma( "loopbound min 15 max 29" ) + for ( dst_blk_x = 0; dst_blk_x < compptr_width_in_blocks; + dst_blk_x++ ) { + + src_ptr = cjpeg_transupp_input; + dst_ptr = cjpeg_transupp_output_data; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i += 2 ) { + + /* copy even row */ + j = 0; + _Pragma( "loopbound min 8 max 8" ) + do { + if ( dst_blk_x < comp_height ) + *dst_ptr++ = *src_ptr++; + j++; + } while ( j < DCTSIZE ); + + /* copy odd row with sign change */ + j = 0; + _Pragma( "loopbound min 8 max 8" ) + do { + if ( dst_blk_x < comp_height ) + *dst_ptr++ = - *src_ptr++; + j++; + } while ( j < DCTSIZE ); + } + } + } + } + } + } +} + + +/* + 90 degree rotation is equivalent to + 1. Transposing the image; + 2. Horizontal mirroring. + These two steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_rot_90( j_compress_ptr dstinfo ) +{ + unsigned int MCU_cols, comp_width, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + + /* + Because of the horizontal mirror step, we can't process partial iMCUs at the + (output) right edge properly. They just get transposed and not mirrored. + */ + MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE ); + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 29; + unsigned int compptr_width_in_blocks = 19; + + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; + ci++, compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) { + + comp_width = MCU_cols * compptr_h_samp_factor; + + _Pragma( "loopbound min 4 max 15" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) { + dst_blk_x = 0; + _Pragma( "loopbound min 10 max 10" ) + for ( ; dst_blk_x < compptr_width_in_blocks; + dst_blk_x += compptr_h_samp_factor ) { + + offset_x = 0; + _Pragma( "loopbound min 1 max 2" ) + for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) { + + src_ptr = cjpeg_transupp_input2; + + if ( dst_blk_x < comp_width ) { + + /* Block is within the mirrorable area. */ + dst_ptr = cjpeg_transupp_output_data2; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + + i++; + + _Pragma( "loopbound min 8 max 8" ) + for ( j = 0; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } else { + /* Edge blocks are transposed but not mirrored. */ + dst_ptr = cjpeg_transupp_output_data2; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + } + } + } + } + } +} + + +/* + 270 degree rotation is equivalent to + 1. Horizontal mirroring; + 2. Transposing the image. + These two steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_rot_270( j_compress_ptr dstinfo ) +{ + unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + + /* + Because of the horizontal mirror step, we can't process partial iMCUs at the + (output) bottom edge properly. They just get transposed and not mirrored. + */ + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 29; + unsigned int compptr_width_in_blocks = 19; + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; + ci++, compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) { + + comp_height = MCU_rows * compptr_v_samp_factor; + + _Pragma( "loopbound min 4 max 15" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) { + dst_blk_x = 0; + _Pragma( "loopbound min 10 max 10" ) + for ( ; dst_blk_x < compptr_width_in_blocks; + dst_blk_x += compptr_h_samp_factor ) { + + offset_x = 0; + _Pragma( "loopbound min 1 max 2" ) + for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) { + + dst_ptr = cjpeg_transupp_output_data3; + + if ( dst_blk_y < comp_height ) { + + /* Block is within the mirrorable area. */ + src_ptr = cjpeg_transupp_input3; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j++ ) { + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } + } else { + + /* Edge blocks are transposed but not mirrored. */ + src_ptr = cjpeg_transupp_input3_2; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_height ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + } + } + } + } + } +} + + +/* + 180 degree rotation is equivalent to + 1. Vertical mirroring; + 2. Horizontal mirroring. + These two steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_rot_180( j_compress_ptr dstinfo ) +{ + unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, + dst_blk_y; + int ci, i, j, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_width_in_blocks = 29; + unsigned int compptr_height_in_blocks = 19; + + + MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE ); + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; ci++, + compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_width_in_blocks = 15, compptr_height_in_blocks = 10 ) { + + comp_width = MCU_cols * compptr_h_samp_factor; + comp_height = MCU_rows * compptr_v_samp_factor; + + _Pragma( "loopbound min 3 max 10" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) { + if ( dst_blk_y < comp_height ) { + + /* Row is within the mirrorable area. */ + + /* Process the blocks that can be mirrored both ways. */ + _Pragma( "loopbound min 14 max 28" ) + for ( dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++ ) { + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i += 2 ) { + j = 0; + /* For even row, negate every odd column. */ + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j += 2 ) { + if ( dst_blk_x < comp_height ) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + } + } + + j = 0; + /* For odd row, negate every even column. */ + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j += 2 ) { + if ( dst_blk_x < comp_height ) { + *dst_ptr++ = - *src_ptr++; + *dst_ptr++ = *src_ptr++; + } + } + } + } + + /* Any remaining right-edge blocks are only mirrored vertically. */ + _Pragma( "loopbound min 1 max 1" ) + for ( ; dst_blk_x < compptr_width_in_blocks; dst_blk_x++ ) { + + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i += 2 ) { + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + *dst_ptr++ = *src_ptr++; + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + *dst_ptr++ = - *src_ptr++; + } + } + } else { + + /* Remaining rows are just mirrored horizontally. */ + dst_blk_x = 0; + /* Process the blocks that can be mirrored. */ + _Pragma( "loopbound min 14 max 28" ) + do { + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + + i = 0; + _Pragma( "loopbound min 32 max 32" ) + while ( i < DCTSIZE2 ) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + i += 2; + dst_ptr += 0; + } + dst_blk_x++; + dst_ptr += 0; + } while ( dst_blk_x < comp_width ); + + /* Any remaining right-edge blocks are only copied. */ + _Pragma( "loopbound min 1 max 1" ) + for ( ; dst_blk_x < compptr_width_in_blocks; dst_blk_x++ ) { + + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + _Pragma( "loopbound min 64 max 64" ) + do { + *dst_ptr++ = *src_ptr++; + i++; + } while ( i < DCTSIZE2 ); + } + } + } + } + } +} + + +/* + Transverse transpose is equivalent to + 1. 180 degree rotation; + 2. Transposition; + or + 1. Horizontal mirroring; + 2. Transposition; + 3. Horizontal mirroring. + These steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_transverse( j_compress_ptr dstinfo ) +{ + unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, + dst_blk_y; + int ci, i, j, offset_x, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 29; + unsigned int compptr_width_in_blocks = 19; + + + MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE ); + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; ci++, + compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) { + + comp_width = MCU_cols * compptr_h_samp_factor; + comp_height = MCU_rows * compptr_v_samp_factor; + + _Pragma( "loopbound min 4 max 15" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + do { + dst_blk_x = 0; + _Pragma( "loopbound min 10 max 10" ) + do { + offset_x = 0; + _Pragma( "loopbound min 1 max 2" ) + for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) { + + if ( dst_blk_y < comp_height ) { + src_ptr = cjpeg_transupp_input5; + + if ( dst_blk_x < comp_width ) { + /* Block is within the mirrorable area. */ + dst_ptr = cjpeg_transupp_output_data5; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + i++; + _Pragma( "loopbound min 4 max 4" ) + for ( j = 0; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + } else { + /* Right-edge blocks are mirrored in y only */ + dst_ptr = cjpeg_transupp_output_data5; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } + } + } else { + src_ptr = cjpeg_transupp_input5_2; + + if ( dst_blk_x < comp_width ) { + /* Bottom-edge blocks are mirrored in x only */ + dst_ptr = cjpeg_transupp_output_data5; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + i++; + _Pragma( "loopbound min 8 max 8" ) + for ( j = 0; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } else { + /* At lower right corner, just transpose, no mirroring */ + dst_ptr = cjpeg_transupp_output_data5; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + dst_blk_x += compptr_h_samp_factor; + } + } while ( dst_blk_x < compptr_width_in_blocks ); + offset_y++; + } while ( offset_y < compptr_v_samp_factor ); + } + } +} + + +/* + Main functions +*/ + +void _Pragma ( "entrypoint" ) cjpeg_transupp_main( void ) +{ + cjpeg_transupp_dstinfo.image_width = 227; + cjpeg_transupp_dstinfo.image_height = 149; + + cjpeg_transupp_do_flip_v( &cjpeg_transupp_dstinfo ); + + cjpeg_transupp_dstinfo.image_width = 149; + cjpeg_transupp_dstinfo.image_height = 227; + + cjpeg_transupp_do_rot_90( &cjpeg_transupp_dstinfo ); + cjpeg_transupp_do_rot_270( &cjpeg_transupp_dstinfo ); + + cjpeg_transupp_dstinfo.image_width = 227; + cjpeg_transupp_dstinfo.image_height = 149; + + cjpeg_transupp_do_rot_180( &cjpeg_transupp_dstinfo ); + + cjpeg_transupp_dstinfo.image_width = 149; + cjpeg_transupp_dstinfo.image_height = 227; + + cjpeg_transupp_do_transverse( &cjpeg_transupp_dstinfo ); +} + + +int main(int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsCompletecomp_info[] */ + int component_index; + + /* horizontal sampling factor (1..4) */ + int h_samp_factor; + + /* vertical sampling factor (1..4) */ + int v_samp_factor; + + /* quantization table selector (0..3) */ + int quant_tbl_no; + + /* + These values may vary between scans. For compression, they must be supplied + by parameter setup; for decompression, they are read from the SOS marker. + The decompressor output side may not use these variables. + */ + + /* DC entropy table selector (0..3) */ + int dc_tbl_no; + + /* AC entropy table selector (0..3) */ + int ac_tbl_no; + + /* Remaining fields should be treated as private by applications. */ + + /* + These values are computed during compression or decompression startup: + Component's size in DCT blocks. Any dummy blocks added to complete an MCU + are not counted; therefore these values do not depend on whether a scan is + interleaved or not. + */ + unsigned int width_in_blocks; + unsigned int height_in_blocks; + + /* + Size of a DCT block in samples. Always DCTSIZE for compression. For + decompression this is the size of the output from one DCT block, reflecting + any scaling we choose to apply during the IDCT step. Values of 1,2,4,8 are + likely to be supported. Note that different components may receive different + IDCT scalings. + */ + int DCT_scaled_size; + + /* + The downsampled dimensions are the component's actual, unpadded number of + samples at the main buffer (preprocessing/compression interface), thus + downsampled_width = ceil(image_width * Hi/Hmax) and similarly for height. + For decompression, IDCT scaling is included, so + downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + + /* actual width in samples */ + unsigned int downsampled_width; + + /* actual height in samples */ + unsigned int downsampled_height; + + /* + This flag is used only for decompression. In cases where some of the + components will be ignored (eg grayscale output from YCbCr image), we can + skip most computations for the unused components. + */ + + /* do we need the value of this component? */ + int component_needed; + + /* + These values are computed before starting a scan of the component. The + decompressor output side may not use these variables. + */ + + /* number of blocks per MCU, horizontally */ + int MCU_width; + + /* number of blocks per MCU, vertically */ + int MCU_height; + + /* MCU_width * MCU_height */ + int MCU_blocks; + + /* MCU width in samples, MCU_width*DCT_scaled_size */ + int MCU_sample_width; + + /* # of non-dummy blocks across in last MCU */ + int last_col_width; + + /* # of non-dummy blocks down in last MCU */ + int last_row_height; + + /* + Saved quantization table for component; (void*)0 if none yet saved. See + jdinput.c comments about the need for this information. This field is + currently used only for decompression. + */ + JQUANT_TBL *quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void *dct_table; +} jpeg_component_info; + + +/* + The script for encoding a multiple-scan file is an array of these: +*/ + +typedef struct { + /* number of components encoded in this scan */ + int comps_in_scan; + + /* their SOF/comp_info[] indexes */ + int component_index[ 4 ]; + + /* progressive JPEG spectral selection parms */ + int Ss, Se; + + /* progressive JPEG successive approx. parms */ + int Ah, Al; +} jpeg_scan_info; + + +/* + Known color spaces. +*/ + +typedef enum { + /* error/unspecified */ + JCS_UNKNOWN, + + /* monochrome */ + JCS_GRAYSCALE, + + /* red/green/blue */ + JCS_RGB, + + /* Y/Cb/Cr (also known as YUV) */ + JCS_YCbCr, + + /* C/M/Y/K */ + JCS_CMYK, + + /* Y/Cb/Cr/K */ + JCS_YCCK +} J_COLOR_SPACE; + + +/* + DCT/IDCT algorithm options. +*/ + +typedef enum { + /* slow but accurate integer algorithm */ + JDCT_ISLOW, + + /* faster, less accurate integer method */ + JDCT_IFAST, + + /* floating-point: accurate, fast on fast HW */ + JDCT_FLOAT +} J_DCT_METHOD; + + +/* + Common fields between JPEG compression and decompression master structs. +*/ + +#define jpeg_common_fields \ + /* Error handler module */\ + struct jpeg_error_mgr *err; \ + /* Memory manager module */\ + struct jpeg_memory_mgr *mem; \ + /* Progress monitor, or (void*)0 if none */\ + struct jpeg_progress_mgr *progress; \ + /* Available for use by application */\ + void *client_data; \ + /* So common code can tell which is which */\ + int is_decompressor; \ + /* For checking call sequence validity */\ + int global_state + + +/* + Routines that are to be used by both halves of the library are declared to + receive a pointer to this structure. There are no actual instances of + jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. +*/ + +struct jpeg_common_struct { + /* Fields common to both master struct types */ + jpeg_common_fields; + + /* + Additional fields follow in an actual jpeg_compress_struct or + jpeg_decompress_struct. All three structs must agree on these initial + fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct *j_common_ptr; +typedef struct jpeg_compress_struct *j_compress_ptr; +typedef struct jpeg_decompress_struct *j_decompress_ptr; + + +/* + Master record for a compression instance +*/ + +struct jpeg_compress_struct { + /* Fields shared with jpeg_decompress_struct */ + jpeg_common_fields; + + /* Destination for compressed data */ + struct jpeg_destination_mgr *dest; + + /* + Description of source image --- these fields must be filled in by outer + application before starting compression. in_color_space must be correct + before you can even call jpeg_set_defaults(). + */ + + /* input image width */ + unsigned int image_width; + + /* input image height */ + unsigned int image_height; + + /* # of color components in input image */ + int input_components; + + /* colorspace of input image */ + J_COLOR_SPACE in_color_space; + + /* image gamma of input image */ + double input_gamma; + + /* + Compression parameters --- these fields must be set before calling + jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + initialize everything to reasonable defaults, then changing anything the + application specifically wants to change. That way you won't get burnt when + new parameters are added. Also note that there are several helper routines + to simplify changing parameters. + */ + + /* bits of precision in image data */ + int data_precision; + + /* # of color components in JPEG image */ + int num_components; + + /* colorspace of JPEG image */ + J_COLOR_SPACE jpeg_color_space; + + /* comp_info[i] describes component that appears i'th in SOF */ + jpeg_component_info *comp_info; + + /* ptrs to coefficient quantization tables, or (void*)0 if not defined */ + JQUANT_TBL *quant_tbl_ptrs[ 4 ]; + + /* ptrs to Huffman coding tables, or (void*)0 if not defined */ + JHUFF_TBL *dc_huff_tbl_ptrs[ 4 ]; + JHUFF_TBL *ac_huff_tbl_ptrs[ 4 ]; + + /* L values for DC arith-coding tables */ + unsigned char arith_dc_L[ 16 ]; + + /* U values for DC arith-coding tables */ + unsigned char arith_dc_U[ 16 ]; + + /* Kx values for AC arith-coding tables */ + unsigned char arith_ac_K[ 16 ]; + + /* # of entries in scan_info array */ + int num_scans; + + /* + script for multi-scan file, or (void*)0 + The default value of scan_info is (void*)0, which causes a single-scan + sequential JPEG file to be emitted. To create a multi-scan file, set + num_scans and scan_info to point to an array of scan definitions. + */ + const jpeg_scan_info *scan_info; + + /* 1=caller supplies downsampled data */ + int raw_data_in; + + /* 1=arithmetic coding, 0=Huffman */ + int arith_code; + + /* 1=optimize entropy encoding parms */ + int optimize_coding; + + /* 1=first samples are cosited */ + int CCIR601_sampling; + + /* 1..100, or 0 for no input smoothing */ + int smoothing_factor; + + /* DCT algorithm selector */ + J_DCT_METHOD dct_method; + + + /* + The restart interval can be specified in absolute MCUs by setting + restart_interval, or in MCU rows by setting restart_in_rows (in which case + the correct restart_interval will be figured for each scan). + */ + + /* MCUs per restart, or 0 for no restart */ + unsigned int restart_interval; + + /* if > 0, MCU rows per restart interval */ + int restart_in_rows; + + + /* + Parameters controlling emission of special markers. + */ + + /* should a JFIF marker be written? */ + int write_JFIF_header; + + /* What to write for the JFIF version number */ + unsigned char JFIF_major_version; + unsigned char JFIF_minor_version; + + /* + These three values are not used by the JPEG code, merely copied into the + JFIF APP0 marker. density_unit can be 0 for unknown, 1 for dots/inch, or 2 + for dots/cm. Note that the pixel aspect ratio is defined by + X_density/Y_density even when density_unit=0. + */ + + /* JFIF code for pixel size units */ + unsigned char density_unit; + + /* Horizontal pixel density */ + unsigned short X_density; + + /* Vertical pixel density */ + unsigned short Y_density; + + /* should an Adobe marker be written? */ + int write_Adobe_marker; + + /* + State variable: index of next scanline to be written to + jpeg_write_scanlines(). Application may use this to control its processing + loop, e.g., "while (next_scanline < image_height)". + */ + + /* 0 .. image_height-1 */ + unsigned int next_scanline; + + + /* + Remaining fields are known throughout compressor, but generally should not + be touched by a surrounding application. + */ + + /* + These fields are computed during compression startup + */ + + /* 1 if scan script uses progressive mode */ + int progressive_mode; + + /* largest h_samp_factor */ + int max_h_samp_factor; + + /* largest v_samp_factor */ + int max_v_samp_factor; + + /* + # of iMCU rows to be input to coef ctlr + The coefficient controller receives data in units of MCU rows as defined for + fully interleaved scans (whether the JPEG file is interleaved or not). There + are v_samp_factor * DCTSIZE sample rows of each component in an "iMCU" + (interleaved MCU) row. + */ + unsigned int total_iMCU_rows; + + /* + These fields are valid during any one scan. They describe the components + and MCUs actually appearing in the scan. + */ + + /* # of JPEG components in this scan */ + int comps_in_scan; + + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + jpeg_component_info *cur_comp_info[ 4 ]; + + /* # of MCUs across the image */ + unsigned int MCUs_per_row; + + /* # of MCU rows in the image */ + unsigned int MCU_rows_in_scan; + + /* # of DCT blocks per MCU */ + int blocks_in_MCU; + + /* + MCU_membership[i] is index in cur_comp_info of component owning i'th block + in an MCU + */ + int MCU_membership[ 10 ]; + + /* progressive JPEG parameters for scan */ + int Ss, Se, Ah, Al; + + /* + Links to compression subobjects (methods and private variables of modules) + */ + + struct jpeg_comp_master *master; + struct jpeg_c_main_controller *main; + struct jpeg_c_prep_controller *prep; + struct jpeg_c_coef_controller *coef; + struct jpeg_marker_writer *marker; + struct jpeg_color_converter *cconvert; + struct jpeg_downsampler *downsample; + struct jpeg_forward_dct *fdct; + struct jpeg_entropy_encoder *entropy; + + /* workspace for jpeg_simple_progression */ + jpeg_scan_info *script_space; + + int script_space_size; +}; + + +/* + "Object" declarations for JPEG modules that may be supplied or called directly + by the surrounding application. As with all objects in the JPEG library, these + structs only define the publicly visible methods and state variables of a + module. Additional private fields may exist after the public ones. +*/ + +/* + Error handler object +*/ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + void ( *error_exit ) ( j_common_ptr cinfo ); + + /* Conditionally emit a trace or warning message */ + void ( *emit_message ) ( j_common_ptr cinfo, int msg_level ); + + /* Routine that actually outputs a trace or error message */ + void ( *output_message ) ( j_common_ptr cinfo ); + + /* Format a message string for the most recent JPEG error or message */ + void ( *format_message ) ( j_common_ptr cinfo, char *buffer ); + + /* Reset error state variables at start of a new image */ + void ( *reset_error_mgr ) ( j_common_ptr cinfo ); + + /* + The message ID code and any parameters are saved here. A message can have + one string parameter or up to 8 int parameters. + */ + int msg_code; + + union { + int i[ 8 ]; + char s[ 80 ]; + } msg_parm; + + + /* + Standard state variables for error facility + */ + + /* max msg_level that will be displayed */ + int trace_level; + + /* + For recoverable corrupt-data errors, we emit a warning message, but keep + going unless emit_message chooses to abort. emit_message should count + warnings in num_warnings. The surrounding application can check for bad data + by seeing if num_warnings is nonzero at the end of processing. + */ + + /* number of corrupt-data warnings */ + long num_warnings; + + /* + These fields point to the table(s) of error message strings. An application + can change the table pointer to switch to a different message list + (typically, to change the language in which errors are reported). Some + applications may wish to add additional error codes that will be handled by + the JPEG library error mechanism; the second table pointer is used for this + purpose. + + First table includes all errors generated by JPEG library itself. Error + code 0 is reserved for a "no such error string" message. + */ + + /* Library errors */ + const char *const *jpeg_message_table; + + /* Table contains strings 0..last_jpeg_message */ + int last_jpeg_message; + + /* + Second table can be added by application (see cjpeg/djpeg for example). It + contains strings numbered first_addon_message..last_addon_message. + */ + + /* Non-library errors */ + const char *const *addon_message_table; + + /* code for first string in addon table */ + int first_addon_message; + + /* code for last string in addon table */ + int last_addon_message; +}; + + +/* + Progress monitor object +*/ + +struct jpeg_progress_mgr { + void ( *progress_monitor ) ( j_common_ptr cinfo ); + + /* work units completed in this pass */ + long pass_counter; + + /* total number of work units in this pass */ + long pass_limit; + + /* passes completed so far */ + int completed_passes; + + /* total number of passes expected */ + int total_passes; +}; + + +/* + Data destination object for compression +*/ + +struct jpeg_destination_mgr { + /* => next byte to write in buffer */ + unsigned char *next_output_byte; + + /* # of byte spaces remaining in buffer */ + long unsigned int free_in_buffer; + + void ( *init_destination ) ( j_compress_ptr cinfo ); + int ( *empty_output_buffer ) ( j_compress_ptr cinfo ); + void ( *term_destination ) ( j_compress_ptr cinfo ); +}; + + +/* + Memory manager object. + Allocates "small" objects (a few K total), "large" objects (tens of K), and + "really big" objects (virtual arrays with backing store if needed). The memory + manager does not allow individual objects to be freed; rather, each created + object is assigned to a pool, and whole pools can be freed at once. This is + faster and more convenient than remembering exactly what to free, especially + where malloc()/free() are not too speedy. + NB: alloc routines never return (void*)0. They exit to error_exit if not + successful. +*/ + +typedef struct jvirt_sarray_control *jvirt_sarray_ptr; +typedef struct jvirt_barray_control *jvirt_barray_ptr; + +struct jpeg_memory_mgr { + /* + Method pointers + */ + void *( *alloc_small ) ( + j_common_ptr cinfo, int pool_id, long unsigned int sizeofobject ); + + void *( *alloc_large ) ( + j_common_ptr cinfo, int pool_id, long unsigned int sizeofobject ); + + JSAMPARRAY ( *alloc_sarray ) ( + j_common_ptr cinfo, int pool_id, unsigned int samplesperrow, + unsigned int numrows ); + + JBLOCKARRAY ( *alloc_barray )( + j_common_ptr cinfo, int pool_id, unsigned int blocksperrow, + unsigned int numrows ); + + jvirt_sarray_ptr ( *request_virt_sarray ) ( + j_common_ptr cinfo, int pool_id, int pre_zero, unsigned int samplesperrow, + unsigned int numrows, unsigned int maxaccess ); + + jvirt_barray_ptr ( *request_virt_barray ) ( + j_common_ptr cinfo, int pool_id, int pre_zero, unsigned int blocksperrow, + unsigned int numrows, unsigned int maxaccess ); + + void ( *realize_virt_arrays ) ( j_common_ptr cinfo ); + + JSAMPARRAY ( *access_virt_sarray ) ( + j_common_ptr cinfo, jvirt_sarray_ptr ptr, unsigned int start_row, + unsigned int num_rows, int writable ); + + JBLOCKARRAY ( *access_virt_barray ) ( + j_common_ptr cinfo, jvirt_barray_ptr ptr, unsigned int start_row, + unsigned int num_rows, int writable ); + + void ( *free_pool ) ( j_common_ptr cinfo, int pool_id ); + + void ( *self_destruct ) ( j_common_ptr cinfo ); + + /* + Limit on memory allocation for this JPEG object. (Note that this is merely + advisory, not a guaranteed maximum; it only affects the space used for + virtual-array buffers.) May be changed by outer application after creating + the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + +#endif /* JPEGLIB_H */ diff --git a/all_pairs/source/cjpeg_wrbmp/ChangeLog.txt b/all_pairs/source/cjpeg_wrbmp/ChangeLog.txt new file mode 100644 index 0000000..df21770 --- /dev/null +++ b/all_pairs/source/cjpeg_wrbmp/ChangeLog.txt @@ -0,0 +1,104 @@ +File: cjpeg_jpeg6b_wrbmp.c +Original provenience: + +2017-04-18: +- Annotated cjpeg_wrbmp_main as entry-point for timing analysis + +2015-10-14: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Changed struct name to cjpeg_jpeg6b_wrbmp_name +- Changed the global variable from {name} to cjpeg_jpeg6b_wrbmp_{name} +- Changed the functions from {name} to cjpeg_jpeg6b_wrbmp_{name} +- Removed code in comment +- Added cjpeg_jpeg6b_wrbmp_main() +- Added cjpeg_jpeg6b_wrbmp_return() +- Added cjpeg_jpeg6b_wrbmp_init() +- Added forward declaration of the functions +- Removed unused variables: test_image[] and color_map[] +- Applied Code Style + +File: input.c +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed _jpeg6b_ from the prefix +- Changed the global variable from colormap to cjpeg_jpeg6b_wrbmp_colormap +- Removed unused variables: test_image[] and color_map[] +- Moved initialization of cjpeg_jpeg6b_wrbmp_colormap to function. This function is called from cjpeg_jpeg6b_wrbmp_init function +- Applied Code Style + +File: cderror.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed _jpeg6b_ from the prefix +- Changed JMESSAGE to CJPEG_JPEG6B_WRBMP_JMESSAGE +- Changed JMAKE_ENUM_LIST to CJPEG_JPEG6B_WRBMP_JMAKE_ENUM_LIST +- Applied Code Style + + +File: cdjpeg.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Rename structs and typedef to cjpeg_jpeg6b_wrbmp_{name} +- Removed unused defines + +File: jconfig.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Change defines to CJPEG_JPEG6B_WRBMP_{NAME} +- Removed _jpeg6b_ from the prefix +- Applied Code Style + + +File: jerror.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed error and warning defines +- Removed _jpeg6b_ from the prefix +- Applied Code Style + + +File: jmorecfg.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed unused comments +- Removed _jpeg6b_ from the prefix +- Removed unused defines +- Removed unused typedefs +- Applied Code Style + + +File: jpeglib.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Used define value directly +- Remove unused typedefs, defines +- Removed _jpeg6b_ from the prefix +- Changed struct name to cjpeg_jpeg6b_wrbmp_{name} +- Changed define {name} to cjpeg_jpeg6b_wrbmp_{name} +- Added generic TACLeBench header to line 1 +- Applied Code Style + + + + diff --git a/all_pairs/source/cjpeg_wrbmp/README b/all_pairs/source/cjpeg_wrbmp/README new file mode 100644 index 0000000..fa69a18 --- /dev/null +++ b/all_pairs/source/cjpeg_wrbmp/README @@ -0,0 +1,383 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 6a of 7-Feb-96 +================================= + +This distribution contains the sixth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +Serious users of this software (particularly those incorporating it into +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to +our electronic mailing list. Mailing list members are notified of updates +and have a chance to participate in technical discussions, etc. + +This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim +Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi, +Ge' Weijers, and other members of the Independent JPEG Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +RELATED SOFTWARE Other stuff you should get. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.doc How to configure and install the IJG software. + usage.doc Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.doc). + wizard.doc Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.doc How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.doc Overview of the JPEG library's internal structure. + filelist.doc Road map of IJG files. + coderules.doc Coding style rules --- please read if you contribute code. + +Please read at least the files install.doc and usage.doc. Useful information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image compression and +decompression. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. JPEG is intended for compressing +"real-world" scenes; line drawings, cartoons and other non-realistic images +are not its strong suit. JPEG is lossy, meaning that the output image is not +exactly identical to the input image. Hence you must not use JPEG if you +have to have identical output bits. However, on typical photographic images, +very good compression levels can be obtained with no visible change, and +remarkably high compression levels are possible if you can tolerate a +low-quality image. For more details, see the references, or just experiment +with various compression settings. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +For legal reasons, we are not distributing code for the arithmetic-coding +variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting +the hierarchical or lossless processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. We have also included +"jpegtran", a utility for lossless transcoding between different JPEG +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for +inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-1996, Thomas G. Lane. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The configuration script "configure" was produced with GNU Autoconf. It +is copyright by the Free Software Foundation but is freely distributable. + +It appears that the arithmetic coding option of the JPEG spec is covered by +patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot +legally be used without obtaining one or more licenses. For this reason, +support for arithmetic coding has been removed from the free JPEG software. +(Since arithmetic coding provides only a marginal gain over the unpatented +Huffman mode, it is unlikely that very many implementations will support it.) +So far as we are aware, there are no patent restrictions on the remaining +code. + +WARNING: Unisys has begun to enforce their patent on LZW compression against +GIF encoders and decoders. You will need a license from Unisys to use the +included rdgif.c or wrgif.c files in a commercial or shareware application. +At this time, Unisys is not enforcing their patent against freeware, so +distribution of this package remains legal. However, we intend to remove +GIF support from the IJG package as soon as a suitable replacement format +becomes reasonably popular. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." + + +REFERENCES +========== + +We highly recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article +is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and +IEEE, and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood +City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and +example C code for a multitude of compression methods including JPEG. It is +an excellent source if you are comfortable reading C code but don't know much +about data compression in general. The book's JPEG sample code is far from +industrial-strength, but when you are ready to look at a full implementation, +you've got one here... + +The best full description of JPEG is the textbook "JPEG Still Image Data +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. +The book includes the complete text of the ISO JPEG standards (DIS 10918-1 +and draft DIS 10918-2). This is by far the most complete exposition of JPEG +in existence, and we highly recommend it. + +The JPEG standard itself is not available electronically; you must order a +paper copy through ISO or ITU. (Unless you feel a need to own a certified +official copy, we recommend buying the Pennebaker and Mitchell book instead; +it's much cheaper and includes a great deal of useful explanatory material.) +In the USA, copies of the standard may be ordered from ANSI Sales at (212) +642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI +doesn't take credit card orders, but Global does.) It's not cheap: as of +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% +shipping/handling. The standard is divided into two parts, Part 1 being the +actual specification, while Part 2 covers compliance testing methods. Part 1 +is titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. + +Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO +document. Part 3 is undergoing ISO balloting and is expected to be approved +by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T +T.84. IJG currently does not support any Part 3 extensions. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. A copy of the JFIF spec is available from: + Literature Department + C-Cube Microsystems, Inc. + 1778 McCarthy Blvd. + Milpitas, CA 95035 + phone (408) 944-6300, fax (408) 944-6314 +A PostScript version of this document is available at ftp.uu.net, file +graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube +mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" +to the server to obtain the JFIF document; send the message "help" if you have +trouble. + +The TIFF 6.0 file format specification can be obtained by FTP from sgi.com +(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed +copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from sgi.com or +from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of +the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. libtiff is available +from sgi.com:/graphics/tiff/. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is ftp.uu.net (Internet +address 192.48.96.9). The most recent released version can always be found +there in directory graphics/jpeg. This particular version will be archived +as graphics/jpeg/jpegsrc.v6a.tar.gz. If you are on the Internet, you +can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't +have FTP access, UUNET's archives are also available via UUCP; contact +help@uunet.uu.net for information on retrieving files that way. + +Numerous Internet sites maintain copies of the UUNET files. However, only +ftp.uu.net is guaranteed to have the latest official version. + +You can also obtain this software in DOS-compatible "zip" archive format from +the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe +in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools". +Again, these versions may sometimes lag behind the ftp.uu.net release. + +The JPEG FAQ (Frequently Asked Questions) article is a useful source of +general information about JPEG. It is updated constantly and therefore is +not included in this distribution. The FAQ is posted every two weeks to +Usenet newsgroups comp.graphics.misc, news.answers, and other groups. +You can always obtain the latest version from the news.answers archive at +rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and +.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +RELATED SOFTWARE +================ + +Numerous viewing and image manipulation programs now support JPEG. (Quite a +few of them use this library to do so.) The JPEG FAQ described above lists +some of the more popular free and shareware viewers, and tells where to +obtain them on Internet. + +If you are on a Unix machine, we highly recommend Jef Poskanzer's free +PBMPLUS image software, which provides many useful operations on PPM-format +image files. In particular, it can convert PPM images to and from a wide +range of other formats. You can obtain this package by FTP from ftp.x.org +(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also +a newer update of this package called NETPBM, available from +wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/. +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software +is; you are likely to have difficulty making it work on any non-Unix machine. + +A different free JPEG implementation, written by the PVRG group at Stanford, +is available from havefun.stanford.edu in directory pub/jpeg. This program +is designed for research and experimentation rather than production use; +it is slower, harder to use, and less portable than the IJG code, but it +is easier to read and modify. Also, the PVRG code supports lossless JPEG, +which we do not. + + +FILE FORMAT WARS +================ + +Some JPEG programs produce files that are not compatible with our library. +The root of the problem is that the ISO JPEG committee failed to specify a +concrete file format. Some vendors "filled in the blanks" on their own, +creating proprietary formats that no one else could read. (For example, none +of the early commercial JPEG implementations for the Macintosh were able to +exchange compressed files.) + +The file format we have adopted is called JFIF (see REFERENCES). This format +has been agreed to by a number of major commercial JPEG vendors, and it has +become the de facto standard. JFIF is a minimal or "low end" representation. +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF +Technical Note #2) for "high end" applications that need to record a lot of +additional data about an image. TIFF/JPEG is fairly new and not yet widely +supported, unfortunately. + +The upcoming JPEG Part 3 standard defines a file format called SPIFF. +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should +be able to read the most common variant of SPIFF. SPIFF has some technical +advantages over JFIF, but its major claim to fame is simply that it is an +official standard rather than an informal one. At this point it is unclear +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto +standard. IJG intends to support SPIFF once the standard is frozen, but we +have not decided whether it should become our default output format or not. +(In any case, our decoder will remain capable of reading JFIF indefinitely.) + +Various proprietary file formats incorporating JPEG compression also exist. +We have little or no sympathy for the existence of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, open format standards for JPEG files. Don't +use a proprietary file format! + + +TO DO +===== + +In future versions, we are considering supporting some of the upcoming JPEG +Part 3 extensions --- principally, variable quantization and the SPIFF file +format. + +Tuning the software for better behavior at low quality/high compression +settings is also of interest. The current method for scaling the +quantization tables is known not to be very good at low Q values. + +As always, speeding things up is high on our priority list. + +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/all_pairs/source/cjpeg_wrbmp/cderror.h b/all_pairs/source/cjpeg_wrbmp/cderror.h new file mode 100644 index 0000000..e479834 --- /dev/null +++ b/all_pairs/source/cjpeg_wrbmp/cderror.h @@ -0,0 +1,140 @@ + +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: cderror.h + + Author: Thomas G. Lane. + + This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file defines the error and message codes for the cjpeg/djpeg + applications. These strings are not needed as part of the JPEG library + proper. + Edit this file to add new codes, or to translate the message strings to + some other language. + + Source: Independent JPEG Group's software + + Changes: no major functional changes + + License: See the accompanying README file + + */ + +#ifndef CJPEG_WRBMP_JMESSAGE +#ifndef CDERROR_H +#define CDERROR_H +/*First time through, define the enum list*/ +#define CJPEG_WRBMP_JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined*/ +#define CJPEG_WRBMP_JMESSAGE(code,string) +#endif +#endif + +#ifdef CJPEG_WRBMP_JMAKE_ENUM_LIST + +typedef enum { + +#define CJPEG_WRBMP_JMESSAGE(code,string) code , + +#endif + + CJPEG_WRBMP_JMESSAGE( JMSG_FIRSTADDONCODE = 1000, NULL ) //Must be first entry! + + #ifdef CJPEG_WRBMP_BMP_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADCMAP, "Unsupported BMP colormap format" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADHEADER, "Invalid BMP file: bad header length" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_NOT, "Not a BMP file - does not start with BM" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP, "%ux%u 24-bit BMP image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image" ) + #endif + + #ifdef CJPEG_WRBMP_GIF_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_GIF_BUG, "GIF output got confused" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_CODESIZE, "Bogus GIF codesize %d" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_NOT, "Not a GIF file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF, "%ux%ux%d GIF image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF_BADVERSION, + "Warning: unexpected GIF version number '%c%c%c'" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_BADDATA, "Corrupt data in GIF file" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_ENDCODE, "Premature end of GIF image" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_NOMOREDATA, "Ran out of GIF bits" ) + #endif + + #ifdef CJPEG_WRBMP_PPM_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file" ) + CJPEG_WRBMP_JMESSAGE( JERR_PPM_NOT, "Not a PPM/PGM file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PGM, "%ux%u PGM image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PGM_TEXT, "%ux%u text PGM image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PPM, "%ux%u PPM image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PPM_TEXT, "%ux%u text PPM image" ) + #endif + + #ifdef RLE_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_RLE_BADERROR, "Bogus error code from RLE library" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_EMPTY, "Empty RLE file" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_EOF, "Premature EOF in RLE header" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_MEM, "Insufficient memory for RLE header" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_NOT, "Not an RLE file" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE, "%ux%u full-color RLE file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_GRAY, "%ux%u grayscale RLE file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d" ) + #endif + + #ifdef CJPEG_WRBMP_TARGA_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_TGA_BADCMAP, "Unsupported Targa colormap format" ) + CJPEG_WRBMP_JMESSAGE( JERR_TGA_BADPARMS, "Invalid or unsupported Targa file" ) + CJPEG_WRBMP_JMESSAGE( JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JTRC_TGA, "%ux%u RGB Targa image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_TGA_GRAY, "%ux%u grayscale Targa image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_TGA_MAPPED, "%ux%u colormapped Targa image" ) + #else + CJPEG_WRBMP_JMESSAGE( JERR_TGA_NOTCOMP, "Targa support was not compiled" ) + #endif + + CJPEG_WRBMP_JMESSAGE( JERR_BAD_CMAP_FILE, + "Color map file is invalid or of unsupported format" ) + CJPEG_WRBMP_JMESSAGE( JERR_TOO_MANY_COLORS, + "Output file format cannot handle %d colormap entries" ) + CJPEG_WRBMP_JMESSAGE( JERR_UNGETC_FAILED, "ungetc failed" ) + #ifdef CJPEG_WRBMP_TARGA_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_UNKNOWN_FORMAT, + "Unrecognized input file format --- perhaps you need -targa" ) + #else + CJPEG_WRBMP_JMESSAGE( JERR_UNKNOWN_FORMAT, "Unrecognized input file format" ) + #endif + CJPEG_WRBMP_JMESSAGE( JERR_UNSUPPORTED_FORMAT, "Unsupported output file format" ) + + #ifdef CJPEG_WRBMP_JMAKE_ENUM_LIST + + JMSG_LASTADDONCODE +} CJPEG_WRBMP_ADDON_MESSAGE_CODE; + +#undef CJPEG_WRBMP_JMAKE_ENUM_LIST + #endif + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default*/ +#undef CJPEG_WRBMP_JMESSAGE diff --git a/all_pairs/source/cjpeg_wrbmp/cdjpeg.h b/all_pairs/source/cjpeg_wrbmp/cdjpeg.h new file mode 100644 index 0000000..6c3fc7b --- /dev/null +++ b/all_pairs/source/cjpeg_wrbmp/cdjpeg.h @@ -0,0 +1,105 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: cdjpeg.h + + Author: Thomas G. Lane. + + This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains common declarations for the sample applications + cjpeg and djpeg. It is NOT used by the core JPEG library. + + Source: Independent JPEG Group's software + + Changes: no major functional changes + + License: See the accompanying README file + +*/ +#ifndef CDJPEG_H +#define CDJPEG_H + +#define CJPEG_WRBMP_JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */ +#define CJPEG_WRBMP_JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */ + +#include "jpeglib.h" +#include "jerror.h" /* get library error codes too */ +#include "cderror.h" /* get application-specific error codes */ + +typedef struct cjpeg_wrbmp_cjpeg_source_struct + *cjpeg_wrbmp_cjpeg_source_ptr; + +struct cjpeg_wrbmp_cjpeg_source_struct { + CJPEG_WRBMP_JMETHOD( void, start_input, + ( cjpeg_wrbmp_j_compress_ptr cinfo, + cjpeg_wrbmp_cjpeg_source_ptr sinfo ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JDIMENSION, get_pixel_rows, + ( cjpeg_wrbmp_j_compress_ptr cinfo, + cjpeg_wrbmp_cjpeg_source_ptr sinfo ) ); + CJPEG_WRBMP_JMETHOD( void, finish_input, + ( cjpeg_wrbmp_j_compress_ptr cinfo, + cjpeg_wrbmp_cjpeg_source_ptr sinfo ) ); + + CJPEG_WRBMP_FILE *input_file; + + CJPEG_WRBMP_JSAMPARRAY buffer; + CJPEG_WRBMP_JDIMENSION buffer_height; +}; + + +typedef struct cjpeg_wrbmp_djpeg_dest_struct + *cjpeg_wrbmp_djpeg_dest_ptr; + +struct cjpeg_wrbmp_djpeg_dest_struct { + CJPEG_WRBMP_JMETHOD( void, start_output, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, + cjpeg_wrbmp_djpeg_dest_ptr dinfo ) ); + /* Emit the specified number of pixel rows from the buffer. */ + CJPEG_WRBMP_JMETHOD( void, put_pixel_rows, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, + cjpeg_wrbmp_djpeg_dest_ptr dinfo, + CJPEG_WRBMP_JDIMENSION rows_supplied ) ); + /* Finish up at the end of the image. */ + CJPEG_WRBMP_JMETHOD( void, finish_output, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, + cjpeg_wrbmp_djpeg_dest_ptr dinfo ) ); + + /* Target file spec; filled in by djpeg.c after object is created. */ + CJPEG_WRBMP_FILE *output_file; + + /* Output pixel-row buffer. Created by module init or start_output. + Width is cinfo->output_width * cinfo->output_components; + height is buffer_height. + */ + CJPEG_WRBMP_JSAMPARRAY buffer; + CJPEG_WRBMP_JDIMENSION buffer_height; +} ; + + + +/* + cjpeg/djpeg may need to perform extra passes to convert to or from + the source/destination file format. The JPEG library does not know + about these passes, but we'd like them to be counted by the progress + monitor. We use an expanded progress monitor object to hold the + additional pass count. +*/ + +struct cjpeg_wrbmp_cdjpeg_progress_mgr { + struct cjpeg_wrbmp_jpeg_progress_mgr + pub; /* fields known to JPEG library */ + int completed_extra_passes; /* extra passes completed */ + int total_extra_passes; /* total extra */ + /* last printed percentage stored here to avoid multiple printouts */ + int percent_done; +}; + +typedef struct cjpeg_wrbmp_cdjpeg_progress_mgr + *cjpeg_wrbmp_cd_progress_ptr; + +#endif + diff --git a/all_pairs/source/cjpeg_wrbmp/cjpeg_wrbmp.c b/all_pairs/source/cjpeg_wrbmp/cjpeg_wrbmp.c new file mode 100644 index 0000000..7bef7ab --- /dev/null +++ b/all_pairs/source/cjpeg_wrbmp/cjpeg_wrbmp.c @@ -0,0 +1,225 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: cjpeg_jpeg6b_wrbmp.c + + Author: Thomas G. Lane. + + Function: This file contains routines to write output images in Microsoft "BMP" + format (MS Windows 3.x and OS/2 1.x flavors). + Either 8-bit colormapped or 24-bit full-color format can be written. + No compression is supported. + + These routines may need modification for non-Unix environments or + specialized applications. As they stand, they assume output to + an ordinary stdio stream. + + Source: Independent JPEG Group's software + + Changes: a brief summary of major functional changes (not formatting) + + License: See the accompanying README file + +*/ + +#include "../extra.h" +#include "cdjpeg.h" + +#ifdef CJPEG_WRBMP_BMP_SUPPORTED + +/* + Declaration of global variables +*/ +typedef struct { + struct cjpeg_wrbmp_djpeg_dest_struct pub; /* public fields */ + cjpeg_wrbmp_boolean is_os2; /* saves the OS2 format request flag */ + cjpeg_wrbmp_jvirt_sarray_ptr + whole_image; /* needed to reverse row order */ + CJPEG_WRBMP_JDIMENSION data_width; /* JSAMPLEs per row */ + CJPEG_WRBMP_JDIMENSION + row_width; /* physical width of one row in the BMP file */ + int pad_bytes; /* number of padding bytes needed per row */ + CJPEG_WRBMP_JDIMENSION + cur_output_row; /* next row# to write to virtual array */ +} cjpeg_wrbmp_bmp_dest_struct; + +typedef cjpeg_wrbmp_bmp_dest_struct *cjpeg_wrbmp_bmp_dest_ptr; +extern unsigned char cjpeg_wrbmp_colormap[3][256]; +unsigned char cjpeg_wrbmp_output_array[6144]; +unsigned char *cjpeg_wrbmp_jpeg_stream /*= cjpeg_jpeg6b_wrbmp_output_array*/; +int cjpeg_wrbmp_checksum; + +struct cjpeg_wrbmp_jpeg_decompress_struct + cjpeg_wrbmp_jpeg_dec_1; +struct cjpeg_wrbmp_jpeg_decompress_struct + cjpeg_wrbmp_jpeg_dec_2; +struct cjpeg_wrbmp_djpeg_dest_struct + cjpeg_wrbmp_djpeg_dest; +cjpeg_wrbmp_bmp_dest_struct cjpeg_wrbmp_bmp_dest; + +/* + Forward declaration of functions +*/ +void cjpeg_wrbmp_initInput( void ); +void cjpeg_wrbmp_finish_output_bmp( cjpeg_wrbmp_j_decompress_ptr cinfo); +void cjpeg_wrbmp_write_colormap( cjpeg_wrbmp_j_decompress_ptr + cinfo, + int map_colors, int map_entry_size, + int cMap ); +int cjpeg_wrbmp_putc_modified( int character ); +void cjpeg_wrbmp_init(); +void cjpeg_wrbmp_main(); +int cjpeg_wrbmp_return(); +//int main(); + +/* + Initialization functions +*/ +void cjpeg_wrbmp_init() +{ + cjpeg_wrbmp_initInput(); + + cjpeg_wrbmp_jpeg_dec_1.progress = 0; + cjpeg_wrbmp_jpeg_dec_1.output_height = 30; + cjpeg_wrbmp_jpeg_dec_1.actual_number_of_colors = 256; + cjpeg_wrbmp_jpeg_dec_1.out_color_components = 2; + + cjpeg_wrbmp_jpeg_dec_2.progress = 0; + cjpeg_wrbmp_jpeg_dec_2.output_height = 30; + cjpeg_wrbmp_jpeg_dec_2.actual_number_of_colors = 256; + cjpeg_wrbmp_jpeg_dec_2.out_color_components = 3; + + cjpeg_wrbmp_jpeg_stream = cjpeg_wrbmp_output_array; + + cjpeg_wrbmp_checksum = 0; +} + +/* + Calculation functions +*/ +int cjpeg_wrbmp_putc_modified( int character ) +{ + *( cjpeg_wrbmp_jpeg_stream ) = character; + + ++cjpeg_wrbmp_jpeg_stream; + + cjpeg_wrbmp_checksum += character; + + return character; +} + +void cjpeg_wrbmp_finish_output_bmp( cjpeg_wrbmp_j_decompress_ptr cinfo ) +{ + CJPEG_WRBMP_JDIMENSION row; + cjpeg_wrbmp_cd_progress_ptr progress = + ( cjpeg_wrbmp_cd_progress_ptr ) cinfo->progress; + + // Write the file body from our virtual array + _Pragma( "loopbound min 30 max 30" ) + for ( row = cinfo->output_height; row > 0; --row ) { + if ( progress != 0 ) { + progress->pub.pass_counter = ( long )( cinfo->output_height - row ); + progress->pub.pass_limit = ( long ) cinfo->output_height; + } + } + + if ( progress != 0 ) + progress->completed_extra_passes++; + } + +void cjpeg_wrbmp_write_colormap( cjpeg_wrbmp_j_decompress_ptr + cinfo, + int map_colors, int map_entry_size, int cMap ) +{ + + int num_colors = cinfo->actual_number_of_colors; + int i; + + if ( cMap != 0 ) { + + if ( cinfo->out_color_components == 3 ) { + // Normal case with RGB colormap + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < num_colors; i++ ) { + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[2][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[1][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[0][i] ) ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } + } else { + // Grayscale colormap (only happens with grayscale quantization) + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < num_colors; i++ ) { + + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[2][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[1][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[0][i] ) ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } + } + } else { + // If no colormap, must be grayscale data. Generate a linear "map". + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + cjpeg_wrbmp_putc_modified( i ); + cjpeg_wrbmp_putc_modified( i ); + cjpeg_wrbmp_putc_modified( i ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } + } + + // Pad colormap with zeros to ensure specified number of colormap entries. + _Pragma( "loopbound min 512 max 512" ) + for ( ; i < map_colors; i++ ) { + cjpeg_wrbmp_putc_modified( 0 ); + cjpeg_wrbmp_putc_modified( 0 ); + cjpeg_wrbmp_putc_modified( 0 ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } +} + +void _Pragma( "entrypoint" ) cjpeg_wrbmp_main() +{ + cjpeg_wrbmp_finish_output_bmp( &cjpeg_wrbmp_jpeg_dec_1); + cjpeg_wrbmp_write_colormap( &cjpeg_wrbmp_jpeg_dec_1, 768, 4, 1 ); + + cjpeg_wrbmp_finish_output_bmp( &cjpeg_wrbmp_jpeg_dec_2 ); + cjpeg_wrbmp_write_colormap( &cjpeg_wrbmp_jpeg_dec_2, 768, 4, 1 ); +} + +int cjpeg_wrbmp_return() +{ + return (cjpeg_wrbmp_checksum + (-209330) ) != 0; +} + +int main(int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsCompletecomp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + Any dummy blocks added to complete an MCU are not counted; therefore + these values do not depend on whether a scan is interleaved or not. + */ + CJPEG_WRBMP_JDIMENSION width_in_blocks; + CJPEG_WRBMP_JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + For decompression this is the size of the output from one DCT block, + reflecting any scaling we choose to apply during the IDCT step. + Values of 1,2,4,8 are likely to be supported. Note that different + components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + of samples at the main buffer (preprocessing/compression interface), thus + downsampled_width = ceil(image_width * Hi/Hmax) + and similarly for height. For decompression, IDCT scaling is included, so + downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + CJPEG_WRBMP_JDIMENSION downsampled_width; /* actual width in samples */ + CJPEG_WRBMP_JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + components will be ignored (eg grayscale output from YCbCr image), + we can skip most computations for the unused components. + */ + cjpeg_wrbmp_boolean + component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + See jdinput.c comments about the need for this information. + This field is currently used only for decompression. + */ + CJPEG_WRBMP_JQUANT_TBL *quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void *dct_table; +} cjpeg_wrbmp_jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[4]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} cjpeg_wrbmp_jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct cjpeg_wrbmp_jpeg_marker_struct CJPEG_WRBMP_FAR + *jpeg_saved_marker_ptr; + +struct cjpeg_wrbmp_jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + CJPEG_WRBMP_UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + CJPEG_WRBMP_JOCTET CJPEG_WRBMP_FAR + *data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} CJPEG_WRBMP_J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} CJPEG_WRBMP_J_DCT_METHOD; + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} CJPEG_WRBMP_J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define cjpeg_wrbmp_jpeg_common_fields \ + struct cjpeg_wrbmp_jpeg_error_mgr * err; /* Error handler module */\ + struct cjpeg_wrbmp_jpeg_memory_mgr * mem; /* Memory manager module */\ + struct cjpeg_wrbmp_jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + cjpeg_wrbmp_boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + to receive a pointer to this structure. There are no actual instances of + jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. +*/ +struct cjpeg_wrbmp_jpeg_common_struct { + cjpeg_wrbmp_jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + jpeg_decompress_struct. All three structs must agree on these + initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct cjpeg_wrbmp_jpeg_common_struct + *cjpeg_wrbmp_j_common_ptr; +typedef struct cjpeg_wrbmp_jpeg_compress_struct + *cjpeg_wrbmp_j_compress_ptr; +typedef struct cjpeg_wrbmp_jpeg_decompress_struct + *cjpeg_wrbmp_j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct cjpeg_wrbmp_jpeg_compress_struct { + cjpeg_wrbmp_jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct cjpeg_wrbmp_jpeg_destination_mgr *dest; + + /* Description of source image --- these fields must be filled in by + outer application before starting compression. in_color_space must + be correct before you can even call jpeg_set_defaults(). + */ + + CJPEG_WRBMP_JDIMENSION image_width; /* input image width */ + CJPEG_WRBMP_JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + CJPEG_WRBMP_J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + float input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + initialize everything to reasonable defaults, then changing anything + the application specifically wants to change. That way you won't get + burnt when new parameters are added. Also note that there are several + helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + CJPEG_WRBMP_J_COLOR_SPACE + jpeg_color_space; /* colorspace of JPEG image */ + + cjpeg_wrbmp_jpeg_component_info *comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + CJPEG_WRBMP_JQUANT_TBL *quant_tbl_ptrs[4]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + CJPEG_WRBMP_JHUFF_TBL *dc_huff_tbl_ptrs[4]; + CJPEG_WRBMP_JHUFF_TBL *ac_huff_tbl_ptrs[4]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + CJPEG_WRBMP_UINT8 + arith_dc_L[16]; /* L values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_dc_U[16]; /* U values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_ac_K[16]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const cjpeg_wrbmp_jpeg_scan_info + *scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + sequential JPEG file to be emitted. To create a multi-scan file, + set num_scans and scan_info to point to an array of scan definitions. + */ + + cjpeg_wrbmp_boolean + raw_data_in; /* TRUE=caller supplies downsampled data */ + cjpeg_wrbmp_boolean + arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + cjpeg_wrbmp_boolean + optimize_coding; /* TRUE=optimize entropy encoding parms */ + cjpeg_wrbmp_boolean + CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + CJPEG_WRBMP_J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + restart_interval, or in MCU rows by setting restart_in_rows + (in which case the correct restart_interval will be figured + for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + cjpeg_wrbmp_boolean + write_JFIF_header; /* should a JFIF marker be written? */ + CJPEG_WRBMP_UINT8 + JFIF_major_version; /* What to write for the JFIF version number */ + CJPEG_WRBMP_UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + CJPEG_WRBMP_UINT8 density_unit; /* JFIF code for pixel size units */ + CJPEG_WRBMP_UINT16 X_density; /* Horizontal pixel density */ + CJPEG_WRBMP_UINT16 Y_density; /* Vertical pixel density */ + cjpeg_wrbmp_boolean + write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + jpeg_write_scanlines(). Application may use this to control its + processing loop, e.g., "while (next_scanline < image_height)". + */ + + CJPEG_WRBMP_JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + should not be touched by a surrounding application. + */ + + /* + These fields are computed during compression startup + */ + cjpeg_wrbmp_boolean + progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + CJPEG_WRBMP_JDIMENSION + total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + for fully interleaved scans (whether the JPEG file is interleaved or not). + There are v_samp_factor * DCTSIZE sample rows of each component in an + "iMCU" (interleaved MCU) row. + */ + + /* + These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + cjpeg_wrbmp_jpeg_component_info *cur_comp_info[4]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + CJPEG_WRBMP_JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + CJPEG_WRBMP_JDIMENSION + MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[10]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + cjpeg_wrbmp_jpeg_scan_info + *script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct cjpeg_wrbmp_jpeg_decompress_struct { + cjpeg_wrbmp_jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct cjpeg_wrbmp_jpeg_source_mgr *src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + CJPEG_WRBMP_JDIMENSION + image_width; /* nominal image width (from SOF marker) */ + CJPEG_WRBMP_JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + CJPEG_WRBMP_J_COLOR_SPACE + jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + them to default values. + */ + + CJPEG_WRBMP_J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + float output_gamma; /* image gamma wanted in output */ + + cjpeg_wrbmp_boolean buffered_image; /* TRUE=multiple output passes */ + cjpeg_wrbmp_boolean raw_data_out; /* TRUE=downsampled data wanted */ + + CJPEG_WRBMP_J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + cjpeg_wrbmp_boolean + do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + cjpeg_wrbmp_boolean + do_block_smoothing; /* TRUE=apply interblock smoothing */ + + cjpeg_wrbmp_boolean + quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + CJPEG_WRBMP_J_DITHER_MODE + dither_mode; /* type of color dithering to use */ + cjpeg_wrbmp_boolean + two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + cjpeg_wrbmp_boolean + enable_1pass_quant; /* enable future use of 1-pass quantizer */ + cjpeg_wrbmp_boolean + enable_EXTERNal_quant;/* enable future use of EXTERNal colormap */ + cjpeg_wrbmp_boolean + enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + These fields are computed by jpeg_start_decompress(). + You can also use jpeg_calc_output_dimensions() to determine these values + in advance of calling jpeg_start_decompress(). + */ + + CJPEG_WRBMP_JDIMENSION output_width; /* scaled image width */ + CJPEG_WRBMP_JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + high, space and time will be wasted due to unnecessary data copying. + Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + The application can supply a colormap by setting colormap non-NULL before + calling jpeg_start_decompress; otherwise a colormap is created during + jpeg_start_decompress or jpeg_start_output. + The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + CJPEG_WRBMP_JSAMPARRAY + colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + Application may use this to control its processing loop, e.g., + "while (output_scanline < output_height)". + */ + CJPEG_WRBMP_JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + CJPEG_WRBMP_JDIMENSION + input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + output side. The decompressor will not allow output scan/row number + to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + CJPEG_WRBMP_JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + with which component c's DCT coefficient i (in zigzag order) is known. + It is -1 when no data has yet been received, otherwise it is the point + transform (shift) value for the most recent scan of the coefficient + (thus, 0 at completion of the progression). + This pointer is NULL when reading a non-progressive file. + */ + int ( *coef_bits )[64]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + these fields. Note that the decompressor output side may not use + any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + datastreams when processing abbreviated JPEG datastreams. + */ + + CJPEG_WRBMP_JQUANT_TBL *quant_tbl_ptrs[4]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + CJPEG_WRBMP_JHUFF_TBL *dc_huff_tbl_ptrs[4]; + CJPEG_WRBMP_JHUFF_TBL *ac_huff_tbl_ptrs[4]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + cjpeg_wrbmp_jpeg_component_info *comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + cjpeg_wrbmp_boolean + progressive_mode; /* TRUE if SOFn specifies progressive mode */ + cjpeg_wrbmp_boolean + arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + CJPEG_WRBMP_UINT8 + arith_dc_L[16]; /* L values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_dc_U[16]; /* U values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_ac_K[16]; /* Kx values for AC arith-coding tables */ + + unsigned int + restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + the JPEG library. + */ + cjpeg_wrbmp_boolean + saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + CJPEG_WRBMP_UINT8 JFIF_major_version; /* JFIF version number */ + CJPEG_WRBMP_UINT8 JFIF_minor_version; + CJPEG_WRBMP_UINT8 density_unit; /* JFIF code for pixel size units */ + CJPEG_WRBMP_UINT16 X_density; /* Horizontal pixel density */ + CJPEG_WRBMP_UINT16 Y_density; /* Vertical pixel density */ + cjpeg_wrbmp_boolean + saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + CJPEG_WRBMP_UINT8 + Adobe_transform; /* Color transform code from Adobe marker */ + + cjpeg_wrbmp_boolean + CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + library, the uninterpreted contents of any or all APPn and COM markers + can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + should not be touched by a surrounding application. + */ + + /* + These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + CJPEG_WRBMP_JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + in fully interleaved JPEG scans, but are used whether the scan is + interleaved or not. We define an iMCU row as v_samp_factor DCT block + rows of each component. Therefore, the IDCT output contains + v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + CJPEG_WRBMP_JSAMPLE + *sample_range_limit; /* table for fast range-limiting */ + + /* + These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. + Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + cjpeg_wrbmp_jpeg_component_info *cur_comp_info[4]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + CJPEG_WRBMP_JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + CJPEG_WRBMP_JDIMENSION + MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[10]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + It is either zero or the code of a JPEG marker that has been + read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master *master; + struct jpeg_d_main_controller *main; + struct jpeg_d_coef_controller *coef; + struct jpeg_d_post_controller *post; + struct jpeg_input_controller *inputctl; + struct jpeg_marker_reader *marker; + struct jpeg_entropy_decoder *entropy; + struct jpeg_inverse_dct *idct; + struct jpeg_upsampler *upsample; + struct jpeg_color_deconverter *cconvert; + struct jpeg_color_quantizer *cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + directly by the surrounding application. + As with all objects in the JPEG library, these structs only define the + publicly visible methods and state variables of a module. Additional + private fields may exist after the public ones. +*/ + + +/* Error handler object */ + +struct cjpeg_wrbmp_jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + CJPEG_WRBMP_JMETHOD( void, error_exit, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + /* Conditionally emit a trace or warning message */ + CJPEG_WRBMP_JMETHOD( void, emit_message, + ( cjpeg_wrbmp_j_common_ptr cinfo, int msg_level ) ); + /* Routine that actually outputs a trace or error message */ + CJPEG_WRBMP_JMETHOD( void, output_message, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + /* Format a message string for the most recent JPEG error or message */ + CJPEG_WRBMP_JMETHOD( void, format_message, + ( cjpeg_wrbmp_j_common_ptr cinfo, char *buffer ) ); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + CJPEG_WRBMP_JMETHOD( void, reset_error_mgr, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + + /* The message ID code and any parameters are saved here. + A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + /* + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + */ + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + but keep going unless emit_message chooses to abort. emit_message + should count warnings in num_warnings. The surrounding application + can check for bad data by seeing if num_warnings is nonzero at the + end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + An application can change the table pointer to switch to a different + message list (typically, to change the language in which errors are + reported). Some applications may wish to add additional error codes + that will be handled by the JPEG library error mechanism; the second + table pointer is used for this purpose. + + First table includes all errors generated by JPEG library itself. + Error code 0 is reserved for a "no such error string" message. + */ + const char *const *jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + It contains strings numbered first_addon_message..last_addon_message. + */ + const char *const *addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct cjpeg_wrbmp_jpeg_progress_mgr { + CJPEG_WRBMP_JMETHOD( void, progress_monitor, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct cjpeg_wrbmp_jpeg_destination_mgr { + CJPEG_WRBMP_JOCTET + *next_output_byte; /* => next byte to write in buffer */ + cjpeg_wrbmp_size_x + free_in_buffer; /* # of byte spaces remaining in buffer */ + + CJPEG_WRBMP_JMETHOD( void, init_destination, + ( cjpeg_wrbmp_j_compress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, empty_output_buffer, + ( cjpeg_wrbmp_j_compress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( void, term_destination, + ( cjpeg_wrbmp_j_compress_ptr cinfo ) ); +}; + + +/* Data source object for decompression */ + +struct cjpeg_wrbmp_jpeg_source_mgr { + const CJPEG_WRBMP_JOCTET + *next_input_byte; /* => next byte to read from buffer */ + cjpeg_wrbmp_size_x bytes_in_buffer; /* # of bytes remaining in buffer */ + + CJPEG_WRBMP_JMETHOD( void, init_source, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, fill_input_buffer, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( void, skip_input_data, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, long num_bytes ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, resync_to_restart, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, int desired ) ); + CJPEG_WRBMP_JMETHOD( void, term_source, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); +}; + + +/* Memory manager object. + Allocates "small" objects (a few K total), "large" objects (tens of K), + and "really big" objects (virtual arrays with backing store if needed). + The memory manager does not allow individual objects to be freed; rather, + each created object is assigned to a pool, and whole pools can be freed + at once. This is faster and more convenient than remembering exactly what + to free, especially where malloc()/free() are not too speedy. + NB: alloc routines never return NULL. They exit to error_exit if not + successful. +*/ + +typedef struct jvirt_sarray_control *cjpeg_wrbmp_jvirt_sarray_ptr; +typedef struct jvirt_barray_control *cjpeg_wrbmp_jvirt_barray_ptr; + + +struct cjpeg_wrbmp_jpeg_memory_mgr { + /* Method pointers */ + CJPEG_WRBMP_JMETHOD( void *, alloc_small, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + cjpeg_wrbmp_size_x sizeofobject ) ); + CJPEG_WRBMP_JMETHOD( void CJPEG_WRBMP_FAR *, alloc_large, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + cjpeg_wrbmp_size_x sizeofobject ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JSAMPARRAY, alloc_sarray, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + CJPEG_WRBMP_JDIMENSION samplesperrow, + CJPEG_WRBMP_JDIMENSION numrows ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JBLOCKARRAY, alloc_barray, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + CJPEG_WRBMP_JDIMENSION blocksperrow, + CJPEG_WRBMP_JDIMENSION numrows ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_jvirt_sarray_ptr, + request_virt_sarray, ( cjpeg_wrbmp_j_common_ptr cinfo, + int pool_id, + cjpeg_wrbmp_boolean pre_zero, + CJPEG_WRBMP_JDIMENSION samplesperrow, + CJPEG_WRBMP_JDIMENSION numrows, + CJPEG_WRBMP_JDIMENSION maxaccess ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_jvirt_barray_ptr, + request_virt_barray, ( cjpeg_wrbmp_j_common_ptr cinfo, + int pool_id, + cjpeg_wrbmp_boolean pre_zero, + CJPEG_WRBMP_JDIMENSION blocksperrow, + CJPEG_WRBMP_JDIMENSION numrows, + CJPEG_WRBMP_JDIMENSION maxaccess ) ); + CJPEG_WRBMP_JMETHOD( void, realize_virt_arrays, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JSAMPARRAY, access_virt_sarray, + ( cjpeg_wrbmp_j_common_ptr cinfo, + cjpeg_wrbmp_jvirt_sarray_ptr ptr, + CJPEG_WRBMP_JDIMENSION start_row, + CJPEG_WRBMP_JDIMENSION num_rows, + cjpeg_wrbmp_boolean writable ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JBLOCKARRAY, access_virt_barray, + ( cjpeg_wrbmp_j_common_ptr cinfo, + cjpeg_wrbmp_jvirt_barray_ptr ptr, + CJPEG_WRBMP_JDIMENSION start_row, + CJPEG_WRBMP_JDIMENSION num_rows, + cjpeg_wrbmp_boolean writable ) ); + CJPEG_WRBMP_JMETHOD( void, free_pool, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id ) ); + CJPEG_WRBMP_JMETHOD( void, self_destruct, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + + /* Limit on memory allocation for this JPEG object. (Note that this is + merely advisory, not a guaranteed maximum; it only affects the space + used for virtual-array buffers.) May be changed by outer application + after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + Need not pass marker code since it is stored in cinfo->unread_marker. +*/ +typedef CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, + jpeg_marker_parser_method, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); + +/* + The JPEG library modules define JPEG_INTERNALS before including this file. + The internal structure declarations are read only when that is true. + Applications using the library should not include jpegint.h, but may wish + to include jerror.h. +*/ + +#ifdef CJPEG_JPEG6B_WRBMP_JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/all_pairs/source/cleanupSemaphores.c b/all_pairs/source/cleanupSemaphores.c new file mode 100644 index 0000000..71ff989 --- /dev/null +++ b/all_pairs/source/cleanupSemaphores.c @@ -0,0 +1,10 @@ +#include + +int main(){ + sem_unlink("/firstTacleSem"); + sem_unlink("/secondTacleSem"); + sem_unlink("/thirdTacleSem"); + sem_unlink("/fourthTacleSem"); + //no longer in use; delete last line after running once + //sem_unlink("/cacheTacleSem"); +} diff --git a/all_pairs/source/dijkstra/ChangeLog.txt b/all_pairs/source/dijkstra/ChangeLog.txt new file mode 100644 index 0000000..f96350b --- /dev/null +++ b/all_pairs/source/dijkstra/ChangeLog.txt @@ -0,0 +1,44 @@ +File: dijkstra.c +Original provenience: network section of MiBench + +2015-11-30: +- Replaced "NULL" with "0", remove #include of glibc_common.h +- Removed commented code referring to variable "qKill" +- Made ch, i, iPrev, iNode, iCost and iDist local variables +- Stripped (inconsistently applied) Hungarian notation, replaced + prefix "q" with prefix "queue" for global variables, renamed + "next_in" to "queueNext" and "qNew" to "newItem" +- Initialize queueHead statically (like queueCount and queueNext) +- Prefixed all functions and global variables with "dijkstra_", + renaming "dijkstra" to "dijkstra_find" +- Calculate a checksum in dijkstra_main, return its value in new + function dijkstra_return +- Added (empty) function dijkstra_init and a main function +- Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions +- Added function prototypes +- Applied code formatting with astyle as in the example +- Added general TACLeBench header to beginning of source code + +2016-03-15: +- Return 0 if checksum is as expected, -1 otherwise +- Make all initializations explicit +- Touch input matrix with volatile to rule out optimizations +- Add entrypoint pragma + +2016-06-14: +- Removed cast to make C++ compiler happy + +Files: input.h, input.c +Original provenience: network section of MiBench + +2015-11-30: +- Prefix global variable "AdjMatrix" with "dijkstra_" +- Applied code formatting with astyle as in the example + +File: glibc_common.h +Original provenience: network section of MiBench + +2015-11-30: +- Removed file diff --git a/all_pairs/source/dijkstra/dijkstra.c b/all_pairs/source/dijkstra/dijkstra.c new file mode 100644 index 0000000..af86ea6 --- /dev/null +++ b/all_pairs/source/dijkstra/dijkstra.c @@ -0,0 +1,204 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: dijkstra + + Author: unknown + + Function: dijkstra finds the shortest path between nodes in a graph + + Source: network section of MiBench + + Changes: Made some variables local, compute checksum + + License: GPL + +*/ + +#include "../extra.h" +#include "input.h" + +/* + Definitions of symbolic constants +*/ +#define NONE 9999 +#define OUT_OF_MEMORY -1 +#define QUEUE_SIZE 1000 + +/* + Type declarations +*/ +struct _NODE { + int dist; + int prev; +}; + +struct _QITEM { + int node; + int dist; + int prev; + struct _QITEM *next; +}; + +/* + Global variable definitions +*/ +struct _NODE dijkstra_rgnNodes[NUM_NODES]; + +int dijkstra_queueCount; +int dijkstra_queueNext; +struct _QITEM *dijkstra_queueHead; +struct _QITEM dijkstra_queueItems[QUEUE_SIZE]; + +int dijkstra_checksum = 0; + +/* + Forward declaration of functions +*/ +void dijkstra_init( void ); +int dijkstra_return( void ); +int dijkstra_enqueue( int node, int dist, int prev ); +void dijkstra_dequeue( int *node, int *dist, int *prev ); +int dijkstra_qcount( void ); +int dijkstra_find( int chStart, int chEnd ); +void dijkstra_main( void ); +//int main( void ); + +void dijkstra_init( void ) +{ + int i, k; + volatile int x = 0; + _Pragma( "loopbound min 100 max 100" ) + for ( i = 0; i < NUM_NODES; i++ ) { + _Pragma( "loopbound min 100 max 100" ) + for ( k = 0; k < NUM_NODES; k++ ) { + dijkstra_AdjMatrix[i][k] ^= x; + } + } + + dijkstra_queueCount = 0; + dijkstra_queueNext = 0; + dijkstra_queueHead = ( struct _QITEM * )0; + + dijkstra_checksum = 0; +} + +int dijkstra_return( void ) +{ + return ( ( dijkstra_checksum == 25 ) ? 0 : -1 ); +} + +int dijkstra_enqueue( int node, int dist, int prev ) +{ + struct _QITEM *newItem = &dijkstra_queueItems[dijkstra_queueNext]; + struct _QITEM *last = dijkstra_queueHead; + + if ( ++dijkstra_queueNext >= QUEUE_SIZE ) + return OUT_OF_MEMORY; + newItem->node = node; + newItem->dist = dist; + newItem->prev = prev; + newItem->next = 0; + + if ( !last ) + dijkstra_queueHead = newItem; + else { + /* TODO: where does this magic loop bound come from? */ + _Pragma( "loopbound min 0 max 313" ) + while ( last->next ) + last = last->next; + last->next = newItem; + } + dijkstra_queueCount++; + return 0; +} + +void dijkstra_dequeue( int *node, int *dist, int *prev ) +{ + if ( dijkstra_queueHead ) { + *node = dijkstra_queueHead->node; + *dist = dijkstra_queueHead->dist; + *prev = dijkstra_queueHead->prev; + dijkstra_queueHead = dijkstra_queueHead->next; + dijkstra_queueCount--; + } +} + +int dijkstra_qcount( void ) +{ + return ( dijkstra_queueCount ); +} + +int dijkstra_find( int chStart, int chEnd ) +{ + int ch; + int prev, node; + int cost, dist; + int i; + + _Pragma( "loopbound min 100 max 100" ) + for ( ch = 0; ch < NUM_NODES; ch++ ) { + dijkstra_rgnNodes[ch].dist = NONE; + dijkstra_rgnNodes[ch].prev = NONE; + } + + if ( chStart == chEnd ) { + } else { + dijkstra_rgnNodes[chStart].dist = 0; + dijkstra_rgnNodes[chStart].prev = NONE; + + if ( dijkstra_enqueue ( chStart, 0, NONE ) == OUT_OF_MEMORY ) + return OUT_OF_MEMORY; + + /* TODO: where does this magic loop bound come from? */ + _Pragma( "loopbound min 618 max 928" ) + while ( dijkstra_qcount() > 0 ) { + dijkstra_dequeue ( &node, &dist, &prev ); + _Pragma( "loopbound min 100 max 100" ) + for ( i = 0; i < NUM_NODES; i++ ) { + if ( ( cost = dijkstra_AdjMatrix[node][i] ) != NONE ) { + if ( ( NONE == dijkstra_rgnNodes[i].dist ) || + ( dijkstra_rgnNodes[i].dist > ( cost + dist ) ) ) { + dijkstra_rgnNodes[i].dist = dist + cost; + dijkstra_rgnNodes[i].prev = node; + if ( dijkstra_enqueue ( i, dist + cost, node ) == OUT_OF_MEMORY ) + return OUT_OF_MEMORY; + } + } + } + } + } + return 0; +} + +void _Pragma( "entrypoint" ) dijkstra_main( void ) +{ + int i, j; + + /* finds 20 shortest paths between nodes */ + _Pragma( "loopbound min 20 max 20" ) + for ( i = 0, j = NUM_NODES / 2; i < 20; i++, j++ ) { + j = j % NUM_NODES; + if ( dijkstra_find( i, j ) == OUT_OF_MEMORY ) { + dijkstra_checksum += OUT_OF_MEMORY; + return; + } else + dijkstra_checksum += dijkstra_rgnNodes[j].dist; + dijkstra_queueNext = 0; + } +} + +int main(int argc, char** argv ) +{ + SET_UP + for(jobsComplete=-1; jobsComplete=0 ? x : -(x)) +#define FILTER 0 +#define EXPAND 1 +#define IS == +#define ISNT != +#define AND && +#define OR || + +#define NUM_LEVELS 4 + + +/* + Forward declaration of functions +*/ + +void epic_init( void ); +void epic_build_pyr( float *image, int x_size, int y_size, int num_levels, + float *lo_filter, float *hi_filter, int filter_size ); +void epic_build_level( float *image, int level_x_size, int level_y_size, + float *lo_filter, float *hi_filter, + int filter_size, float *result_block ); +void epic_internal_transpose( float *mat, int rows, int cols ); +void epic_internal_filter( float *image, int x_dim, int y_dim, float *filt, + float *temp, int x_fdim, int y_fdim, + int xgrid_start, int xgrid_step, int ygrid_start, + int ygrid_step, float *result ); +void epic_reflect1( float *filt, int x_dim, int y_dim, int x_pos, int y_pos, + float *result, int f_or_e ); +void epic_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +float epic_filtertemp[FILTER_SIZE]; +float epic_hi_imagetemp[X_SIZE * Y_SIZE / 2]; +float epic_lo_imagetemp[X_SIZE * Y_SIZE / 2]; + +static float epic_lo_filter[FILTER_SIZE] = { + -0.0012475221, -0.0024950907, 0.0087309530, 0.0199579580, + -0.0505290000, -0.1205509700, 0.2930455800, + 0.7061761600, + 0.2930455800, -0.1205509700, -0.0505290000, + 0.0199579580, 0.0087309530, -0.0024950907, -0.0012475221 +}; + +static float epic_hi_filter[FILTER_SIZE] = { + 0.0012475221, -0.0024950907, -0.0087309530, 0.0199579580, + 0.0505290000, -0.1205509700, -0.2930455800, + 0.7061761600, + -0.2930455800, -0.1205509700, 0.0505290000, + 0.0199579580, -0.0087309530, -0.0024950907, 0.0012475221 +}; + + +/* + Initialization function +*/ + +void epic_init( void ) +{ + int i; + + _Pragma( "loopbound min 4096 max 9801" ) + for ( i = 0; i < X_SIZE * Y_SIZE; ++i ) + epic_image[i] *= SCALE_FACTOR; +} + + +/* + Algorithm core functions +*/ + +/* + ====================================================================== + epic_build_pyr() -- builds a separable QMF-style pyramid. The pyramid + is written over the original image. NOTE: the image size must be + divisible by 2^num_levels, but we do not check this here. + ====================================================================== +*/ +void epic_build_pyr( float *image, int x_size, int y_size, int num_levels, + float *lo_filter, float *hi_filter, int filter_size ) +{ + int x_level, y_level, level; + + x_level = x_size; + y_level = y_size; + + _Pragma( "loopbound min 4 max 4" ) + for ( level = 0; level < num_levels; ++level ){ + epic_build_level( image, x_level, y_level, lo_filter, hi_filter, + filter_size, image ); + x_level /= 2; + y_level /= 2; + } +} + + +/* + ====================================================================== + epic_build_level() -- builds a level of the pyramid by computing 4 + filtered and subsampled images. Since the convolution is separable, + image and result-block can point to the same place! Image order is + lowpass, horizontal, vertical (transposed), and diagonal. + ====================================================================== +*/ +void epic_build_level( float *image, int level_x_size, int level_y_size, + float *lo_filter, float *hi_filter, + int filter_size, float *result_block ) +{ + int total_size = level_x_size * level_y_size; + + /* filter and subsample in the X direction */ + epic_internal_filter ( image, level_x_size, level_y_size, + lo_filter, epic_filtertemp, filter_size, 1, + 0, 2, 0, 1, epic_lo_imagetemp ); + epic_internal_filter ( image, level_x_size, level_y_size, + hi_filter, epic_filtertemp, filter_size, 1, + 1, 2, 0, 1, epic_hi_imagetemp ); + + level_x_size /= 2; + /* now filter and subsample in the Y direction */ + epic_internal_filter ( epic_lo_imagetemp, level_x_size, + level_y_size, /* lowpass */ + lo_filter, epic_filtertemp, 1, filter_size, + 0, 1, 0, 2, result_block ); + epic_internal_filter ( epic_lo_imagetemp, level_x_size, + level_y_size, /* horizontal */ + hi_filter, epic_filtertemp, 1, filter_size, + 0, 1, 1, 2, ( result_block += ( total_size / 4 ) ) ); + epic_internal_filter ( epic_hi_imagetemp, level_x_size, + level_y_size, /* vertical */ + lo_filter, epic_filtertemp, 1, filter_size, + 0, 1, 0, 2, ( result_block += ( total_size / 4 ) ) ); + /* transpose the vertical band for more efficient scanning */ + epic_internal_transpose( result_block, level_y_size / 2, level_x_size ); + epic_internal_filter ( epic_hi_imagetemp, level_x_size, + level_y_size, /* diagonal */ + hi_filter, epic_filtertemp, 1, filter_size, + 0, 1, 1, 2, ( result_block += ( total_size / 4 ) ) ); +} + + +/* + ====================================================================== + In-place matrix tranpose algorithm. Handles non-square matrices, + too! Is there a faster algorithm?? + ====================================================================== +*/ +void epic_internal_transpose( float *mat, int rows, int cols ) +{ + register int swap_pos; + register int modulus = rows * cols - 1; + register int current_pos; + register float swap_val; + + /* loop, ignoring first and last elements */ + _Pragma( "loopbound min 1022 max 2399" ) + for ( current_pos = 1; current_pos < modulus; ++current_pos ) { + /* Compute swap position */ + swap_pos = current_pos; + + _Pragma( "loopbound min 1 max 2" ) + do { + swap_pos = ( swap_pos * cols ) % modulus; + } while ( swap_pos < current_pos ); + + if ( current_pos != swap_pos ) { + swap_val = mat[swap_pos]; + mat[swap_pos] = mat[current_pos]; + mat[current_pos] = swap_val; + } + } +} + + +/* -------------------------------------------------------------------- + Correlate FILT with IMAGE, subsampling according to GRID parameters, + with values placed into result array. TEMP is a temporary + array the size of the filter. EDGES is a string -- see convolve.h. + The convolution is done in 9 sections, where the border sections use + specially computed edge-handling filters (see edges.c). The origin + of the filter is assumed to be (floor(x_fdim/2), floor(y_fdim/2)). + 10/6/89 - approximately optimized the choice of register vars on SPARCS. + ------------------------------------------------------------------------ */ +void epic_internal_filter( float *image, int x_dim, int y_dim, float *filt, + float *temp, int x_fdim, int y_fdim, + int xgrid_start, int xgrid_step, int ygrid_start, + int ygrid_step, float *result ) +{ + //register double sum; + register float sum; + register int x_filt, im_pos, y_filt_lin; + register int y_im_lin, x_pos, filt_size = x_fdim * y_fdim; + register int y_pos, res_pos; + register int last_ctr_col = x_dim - x_fdim; + int last_ctr_row = ( y_dim - y_fdim ) * x_dim; + int first_row, first_col ; + int x_fmid = x_fdim / 2; + int y_fmid = y_fdim / 2; + int x_stop = x_fdim - x_fmid + 1; + int y_stop = y_fdim - y_fmid + 1; + int ygrid_step_full = ygrid_step * x_dim; + int prev_res_pos, x_res_dim = ( x_dim - xgrid_start + xgrid_step - 1 ) / + xgrid_step; + int rt_edge_res_pos = x_res_dim; + + res_pos = 0; + first_col = xgrid_start - x_fmid + xgrid_step; + + _Pragma( "loopbound min 1 max 4" ) + for ( y_pos = ygrid_start - y_fmid - 1; y_pos < 0; y_pos += ygrid_step ) { + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos = xgrid_start - x_fmid; /* top-left corner */ + x_pos < 0; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = y_im_lin = 0; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = y_im_lin; + + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + first_col = x_pos + 1; + epic_reflect1( filt, x_fdim, y_fdim, 0, y_pos, temp, FILTER ); + _Pragma( "loopbound min 41 max 46" ) + for ( x_pos = first_col; /* top edge */ + x_pos < last_ctr_col; + x_pos += xgrid_step ) { + sum = 0.0f; + x_filt = y_im_lin = 0; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = x_pos + y_im_lin; + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + rt_edge_res_pos = res_pos + x_res_dim; /* save this for later ... */ + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos += ( 1 - last_ctr_col ); /* top-right corner */ + x_pos < x_stop; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = y_im_lin = 0; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = y_im_lin + last_ctr_col; + + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + } /* end top */ + + first_row = x_dim * ( y_pos + 1 ); /* need this to go down the sides */ + prev_res_pos = res_pos; + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos = xgrid_start - x_fmid; /* left edge */ + x_pos < 1; + x_pos += xgrid_step ) { + res_pos = prev_res_pos; + epic_reflect1( filt, x_fdim, y_fdim, x_pos, 0, temp, FILTER ); + _Pragma( "loopbound min 41 max 97" ) + for ( y_pos = first_row; y_pos < last_ctr_row; + y_pos += ygrid_step_full ) { + sum = 0.0f; + x_filt = 0, y_im_lin = y_pos; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = y_im_lin; + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; x_filt++ ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + res_pos += x_res_dim; + } + prev_res_pos++; + } + epic_reflect1( filt, x_fdim, y_fdim, 0, 0, temp, FILTER ); + _Pragma( "loopbound min 41 max 97" ) + for ( y_pos = first_row; /* center region of image */ + y_pos < last_ctr_row; + y_pos += ygrid_step_full ) { + res_pos = prev_res_pos; + _Pragma( "loopbound min 41 max 46" ) + for ( x_pos = first_col; + x_pos < last_ctr_col; + x_pos += xgrid_step ) { + sum = 0.0f; + x_filt = 0, y_im_lin = y_pos; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = x_pos + y_im_lin; + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + prev_res_pos += x_res_dim; + } + prev_res_pos = rt_edge_res_pos; + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos += ( 1 - last_ctr_col ); /* right edge */ + x_pos < x_stop; + x_pos += xgrid_step ) { + res_pos = prev_res_pos; + epic_reflect1( filt, x_fdim, y_fdim, x_pos, 0, temp, FILTER ); + _Pragma( "loopbound min 41 max 97" ) + for ( y_pos = first_row; y_pos < last_ctr_row; + y_pos += ygrid_step_full ) { + sum = 0.0f; + x_filt = 0, y_im_lin = y_pos; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; + y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = y_im_lin + last_ctr_col; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + res_pos += x_res_dim; + } + prev_res_pos++; + } /* end mid */ + + res_pos -= ( x_res_dim - 1 ); /* go to lower left corner */ + _Pragma( "loopbound min 1 max 4" ) + for ( y_pos = ( ( y_pos - last_ctr_row ) / x_dim ) + 1; /* bottom */ + y_pos < y_stop; + y_pos += ygrid_step ) { + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos = xgrid_start - x_fmid; /* bottom-left corner */ + x_pos < 1; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = 0, y_im_lin = last_ctr_row; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = y_im_lin; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + epic_reflect1( filt, x_fdim, y_fdim, 0, y_pos, temp, FILTER ); + _Pragma( "loopbound min 41 max 46" ) + for ( x_pos = first_col; /* bottom edge */ + x_pos < last_ctr_col; + x_pos += xgrid_step ) { + sum = 0.0f; + x_filt = 0, y_im_lin = last_ctr_row; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = x_pos + y_im_lin; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos += 1 - last_ctr_col; /* bottom-right corner */ + x_pos < x_stop; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = 0, y_im_lin = last_ctr_row; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = y_im_lin + last_ctr_col; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + } /* end bottom */ + +} /* end of epic_internal_filter */ + + +/* + The following function determine how edges are to be handled + when performing convolutions of images with linear filters. + Any edge handling function which is local and linear may be defined, + except (unfortunately) constants cannot be added. So to treat the + edges as if the image is surrounded by a gray field, you must paste it + into a gray image, convolve, and crop it out... + The main convolution function is called epic_internal_filter. The idea + is that the convolution function calls the edge handling function which + computes a new filter based on the old filter and the distance to the + edge of the image. For example, reflection is done by reflecting the + filter through the appropriate axis and summing. +*/ + +/* + ---------------- EDGE HANDLER ARGUMENTS ------------------------ + filt - floating point array of filter taps. + x_dim, y_dim - x and y dimensions of filt. + x_pos - position of filter relative to the horizontal image edges. Negative + values indicate left edge, positive indicate right edge. Zero + indicates that the filter is not touching either edge. An absolute + value of 1 indicates that the edge tap of the filter is over the + edge pixel of the image. + y_pos - analogous to x_pos. + result - floating point array where the resulting filter will go. The edge + of this filter will be aligned with the image for application... + f_or_e - equal to one of the two constants EXPAND or FILTER. + -------------------------------------------------------------------- +*/ + +/* -------------------------------------------------------------------- + epic_reflect1() - Reflection through the edge pixels. This is the right + thing to do if you are subsampling by 2, since it maintains parity (even + pixels positions remain even, odd ones remain odd). (note: procedure differs + depending on f_or_e parameter). */ +void epic_reflect1( float *filt, int x_dim, int y_dim, int x_pos, int y_pos, + float *result, int f_or_e ) +{ + int filt_sz = x_dim * y_dim; + register int x_start = 0, y_start = 0, x_stop = x_dim, y_stop = filt_sz; + register int y_filt, x_filt, y_edge, x_edge; + register int x_base = ( x_pos > 0 ) ? ( x_dim - 1 ) : 0; + register int y_base = ( y_pos > 0 ) ? ( x_dim * ( y_dim - 1 ) ) : 0; + int x_edge_dist = ( x_pos > 0 ) ? ( x_pos - x_dim ) : ( ( x_pos < -1 ) ? + ( x_pos + 1 ) : 0 ); + int y_edge_dist = x_dim * ( ( y_pos > 0 ) ? ( y_pos - y_dim ) : ( ( + y_pos < -1 ) ? ( y_pos + 1 ) : 0 ) ); + int i; + int mx_pos = ( x_dim / 2 ) + 1; + int my_pos = ( y_dim / 2 ) + 1; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < filt_sz; ++i ) result[i] = 0.0f; + + /* if EXPAND and filter is centered on image edge, do not reflect */ + if ( f_or_e IS EXPAND ) { + if ( x_pos IS mx_pos ) x_stop = ( x_dim + 1 ) / 2; + else + if ( x_pos IS - mx_pos ) { + x_start = x_dim / 2; + x_edge_dist = 0; + } + + if ( y_pos IS my_pos ) y_stop = x_dim * ( ( y_dim + 1 ) / 2 ); + else + if ( y_pos IS - my_pos ) { + y_start = x_dim * ( y_dim / 2 ); + y_edge_dist = 0; + } + } + + y_edge = y_edge_dist; + /* reflect at boundary of image */ + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt = y_start; y_filt < y_stop; y_filt += x_dim ) { + x_edge = x_edge_dist; + _Pragma( "loopbound min 1 max 15" ) + for ( x_filt = y_filt + x_start; x_filt < y_filt + x_stop; ++x_filt ) { + result[abs( y_base - abs( y_edge ) ) + abs( x_base - abs( x_edge ) )] + += filt[x_filt]; + ++x_edge; + } + y_edge += x_dim; + } + + /* if EXPAND and filter is not centered on image edge, mult edge by 2 */ + if ( f_or_e IS EXPAND ) { + if ( ( abs( x_pos ) ISNT mx_pos ) AND ( x_pos ISNT 0 ) ) + _Pragma( "loopbound min 0 max 0" ) + for ( y_filt = x_base; y_filt < filt_sz; y_filt += x_dim ) + result[y_filt] += result[y_filt]; + if ( ( abs( y_pos ) ISNT my_pos ) AND ( y_pos ISNT 0 ) ) + _Pragma( "loopbound min 0 max 0" ) + for ( x_filt = y_base; x_filt < y_base + x_dim; ++x_filt ) + result[x_filt] += result[x_filt]; + } +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) epic_main( void ) +{ + epic_build_pyr( epic_image, X_SIZE, Y_SIZE, NUM_LEVELS, epic_lo_filter, + epic_hi_filter, FILTER_SIZE ); +} + +int epic_return(){ + int i; + int checksum = 0; + for ( i=0 ; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Benchmarks use SET_UP, START_LOOP, STOP_LOOP, and WRITE_TO_FILE +// These are macros so that we can declare and maintain additional state inside +// the benchmark. +#define SET_UP if (argc < 8) {\ + printf("Usage: %s ", argv[0]);\ + exit(1);\ + }\ + char * thisProgram = argv[1];\ + int maxJobs = atoi(argv[2]);\ + char * thisCore = argv[3];\ + char * otherCore = argv[4];\ + char * otherProgram = argv[5];\ + char * runID = argv[6];\ + int lockID = atoi(argv[7]);\ + struct timespec start, end;\ + int jobsComplete;\ + long * startS = malloc(sizeof(long) *maxJobs);\ + long * startN = malloc(sizeof(long) *maxJobs);\ + long * endS = malloc(sizeof(long) *maxJobs);\ + long * endN = malloc(sizeof(long) *maxJobs);\ + char * bigArray;\ + char fileName[strlen(runID) + 5];\ + strcpy(fileName, runID);\ + strcat(fileName, ".txt");\ + mlockall(MCL_CURRENT || MCL_FUTURE);\ + sem_t *firstSem=sem_open("/firstTacleSem", O_CREAT, 644, 0);\ + if (firstSem == SEM_FAILED) {\ + perror("Error opening/creating first semaphore");\ + exit(1);\ + }\ + sem_t *secondSem=sem_open("/secondTacleSem", O_CREAT, 644, 0);\ + if (secondSem == SEM_FAILED) {\ + perror("Error opening/creating second semaphore");\ + exit(1);\ + }\ + int barrier_file = shm_open("/TacleBarrier", O_CREAT | O_RDWR, 644);\ + if (barrier_file == -1) {\ + perror("Error creating shared memory");\ + exit(1);\ + }\ + /* This sets our shared file to be one byte of '\0'*/ \ + if (ftruncate(barrier_file, 1) == -1) {\ + perror("Error setting size of shared memory");\ + exit(1);\ + }\ + char * barrier = mmap(NULL, 1, PROT_WRITE, MAP_SHARED, barrier_file, 0);\ + if (barrier == MAP_FAILED) {\ + perror("Error mapping shared memory");\ + exit(1);\ + }\ + int error;\ + int val; + +#define SAVE_RESULTS if (jobsComplete > -1){\ + startS[jobsComplete]=start.tv_sec;\ + startN[jobsComplete]=start.tv_nsec;\ + endS[jobsComplete]=end.tv_sec;\ + endN[jobsComplete]=end.tv_nsec;} + +#define WRITE_TO_FILE {\ + munlockall();\ + FILE *fp = fopen(fileName, "a");\ + if (fp == NULL) {\ + perror("Error opening file. \n");\ + exit(1);\ + }\ + for(jobsComplete=0; jobsComplete +* $Id: fmref.c,v 1.2 2010-10-04 21:21:26 garus Exp $ +*/ + + +#include "../extra.h" +#include "wcclibm.h" +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif + +// Defines +#define SAMPLING_RATE 250000000 +#define CUTOFF_FREQUENCY 108000000 +#define NUM_TAPS 64 +#define MAX_AMPLITUDE 27000.0 +#define BANDWIDTH 10000 +#define DECIMATION 4 +/* Must be at least NUM_TAPS+1: */ +#define IN_BUFFER_LEN 200 +#define EQUALIZER_BANDS 10 + + +// Type declarations +typedef struct FloatBuffer +{ + float buff[IN_BUFFER_LEN]; + int rpos, rlen; +} +FloatBuffer; +/* Low pass filter: */ +typedef struct LPFData +{ + float coeff[NUM_TAPS]; + float freq; + int taps, decimation; +} +LPFData; +typedef struct EqualizerData +{ + LPFData lpf[EQUALIZER_BANDS + 1]; + FloatBuffer fb[EQUALIZER_BANDS + 1]; + float gain[EQUALIZER_BANDS]; +} +EqualizerData; + +// Global vars +float fmref_lpf_coeff[NUM_TAPS]; +float fmref_eq_cutoffs[EQUALIZER_BANDS + 1] = + { 55.000004f, 77.78174f, 110.00001f, 155.56354f, 220.00002f, 311.12695f, + 440.00003f, 622.25415f, 880.00006f, 1244.5078f, 1760.0001f }; +static int fmref_numiters = 2; + +// Forward declarations +void fmref_fb_compact(FloatBuffer *fb); +int fmref_fb_ensure_writable(FloatBuffer *fb, int amount); +void fmref_get_floats(FloatBuffer *fb); +void fmref_init_lpf_data(LPFData *data, float freq, int taps, int decimation); +void fmref_run_lpf(FloatBuffer *fbin, FloatBuffer *fbout, LPFData *data); +void fmref_run_demod(FloatBuffer *fbin, FloatBuffer *fbout); +void fmref_init_equalizer(EqualizerData *data); +void fmref_run_equalizer(FloatBuffer *fbin, FloatBuffer *fbout, EqualizerData *data); +void fmref_main(void); + +void fmref_init(void) +{ + // dummy init function +} + +int fmref_return(void) +{ + // dummy return value + return 0; +} + +int main(int argc, char **argv){ + + SET_UP + for(jobsComplete=-1; jobsComplete 0) { + /* The low-pass filter will need NUM_TAPS+1 items; read them if we + * need to. */ + if (fmref_fb1.rlen - fmref_fb1.rpos < NUM_TAPS + 1) + fmref_get_floats(&fmref_fb1); + fmref_run_lpf(&fmref_fb1, &fmref_fb2, &fmref_lpf_data); + fmref_run_demod(&fmref_fb2, &fmref_fb3); + fmref_run_equalizer(&fmref_fb3, &fmref_fb4, &eq_data); + + } +} + +void fmref_fb_compact(FloatBuffer *fb) +{ + + int i; + char *source; + char *target; + target = (char*)(fb->buff); + source = (char*)(fb->buff + fb->rpos); + _Pragma( "loopbound min 0 max 60" ) + for (i = 0; i < fb->rlen - fb->rpos; i++) { + target[i] = source[i]; + } + fb->rlen -= fb->rpos; + fb->rpos = 0; +} + +int fmref_fb_ensure_writable(FloatBuffer *fb, int amount) +{ + int available = IN_BUFFER_LEN - fb->rlen; + if (available >= amount) + return 1; + + /* Nope, not enough room, move current contents back to the beginning. */ + fmref_fb_compact(fb); + + available = IN_BUFFER_LEN - fb->rlen; + if (available >= amount) + return 1; + + return 0; +} + +void fmref_get_floats(FloatBuffer *fb) +{ + static int x = 0; + fmref_fb_compact(fb); + + /* Fill the remaining space in fb with 1.0. */ + _Pragma( "loopbound min 200 max 200" ) + while (fb->rlen < IN_BUFFER_LEN) { + fb->buff[fb->rlen++] = (float)x; + x++; + } +} + +void fmref_init_lpf_data(LPFData *data, float freq, int taps, int decimation) +{ + /* Assume that CUTOFF_FREQUENCY is non-zero. See comments in + * StreamIt LowPassFilter.java for origin. */ + float w = 2 * M_PI * freq / SAMPLING_RATE; + int i; + float m = taps - 1.0f; + + data->freq = freq; + data->taps = taps; + data->decimation = decimation; + + _Pragma( "loopbound min 64 max 64" ) + for (i = 0; i < taps; i++) { + if (i - m / 2 == 0.0f) + data->coeff[i] = w / M_PI; + else + data->coeff[i] = sin(w * (i - m / 2)) / M_PI / (i - m / 2) * + (0.54f - 0.46f * cos(2 * M_PI * i / m)); + } +} + +void fmref_run_lpf(FloatBuffer *fbin, FloatBuffer *fbout, LPFData *data) +{ + float sum = 0.0f; + int i = 0; + + _Pragma( "loopbound min 64 max 64" ) + for (i = 0; i < data->taps; i++) { + sum += fbin->buff[fbin->rpos + i] * data->coeff[i]; + } + + fbin->rpos += data->decimation + 1; + + /* Check that there's room in the output buffer; move data if necessary. */ + fmref_fb_ensure_writable(fbout, 1); + fbout->buff[fbout->rlen++] = sum; +} + +void fmref_run_demod(FloatBuffer *fbin, FloatBuffer *fbout) +{ + float temp, gain; + gain = MAX_AMPLITUDE * SAMPLING_RATE / (BANDWIDTH * M_PI); + temp = fbin->buff[fbin->rpos] * fbin->buff[fbin->rpos + 1]; + temp = gain * atan(temp); + fbin->rpos++; + fmref_fb_ensure_writable(fbout, 1); + fbout->buff[fbout->rlen++] = temp; +} + +void fmref_init_equalizer(EqualizerData *data) +{ + int i; + + /* Equalizer structure: there are ten band-pass filters, with + * cutoffs as shown below. The outputs of these filters get added + * together. Each band-pass filter is LPF(high)-LPF(low). */ + _Pragma( "loopbound min 11 max 11" ) + for (i = 0; i < EQUALIZER_BANDS + 1; i++) + fmref_init_lpf_data(&data->lpf[i], fmref_eq_cutoffs[i], 64, 0); + + /* Also initialize member buffers. */ + _Pragma( "loopbound min 11 max 11" ) + for (i = 0; i < EQUALIZER_BANDS + 1; i++) + data->fb[i].rpos = data->fb[i].rlen = 0; + + _Pragma( "loopbound min 10 max 10" ) + for (i = 0; i < EQUALIZER_BANDS; i++) { + // the gain amplifies the middle bands the most + float val = (((float)i) - (((float)(EQUALIZER_BANDS - 1)) / 2.0f)) / 5.0f; + data->gain[i] = val > 0 ? 2.0f - val : 2.0f + val; + } +} + +void fmref_run_equalizer(FloatBuffer *fbin, FloatBuffer *fbout, EqualizerData *data) +{ + int i, rpos; + float lpf_out[EQUALIZER_BANDS + 1]; + float sum = 0.0; + + /* Save the input read location; we can reuse the same input data on all + * of the LPFs. */ + rpos = fbin->rpos; + + /* Run the child filters. */ + _Pragma( "loopbound min 11 max 11" ) + for (i = 0; i < EQUALIZER_BANDS + 1; i++) { + fbin->rpos = rpos; + fmref_run_lpf(fbin, &data->fb[i], &data->lpf[i]); + lpf_out[i] = data->fb[i].buff[data->fb[i].rpos++]; + } + + /* Now process the results of the filters. Remember that each band is + * output(hi)-output(lo). */ + _Pragma( "loopbound min 10 max 10" ) + for (i = 0; i < EQUALIZER_BANDS; i++) + sum += (lpf_out[i + 1] - lpf_out[i]) * data->gain[i]; + + /* Write that result. */ + fmref_fb_ensure_writable(fbout, 1); + fbout->buff[fbout->rlen++] = sum; +} + diff --git a/all_pairs/source/fmref/license.txt b/all_pairs/source/fmref/license.txt new file mode 100644 index 0000000..7029925 --- /dev/null +++ b/all_pairs/source/fmref/license.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/all_pairs/source/fmref/math_private.h b/all_pairs/source/fmref/math_private.h new file mode 100644 index 0000000..58d4354 --- /dev/null +++ b/all_pairs/source/fmref/math_private.h @@ -0,0 +1,178 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + */ + +#ifndef _MATH_PRIVATE_H_ +#define _MATH_PRIVATE_H_ + +#include "wcclibm.h" + +//#include +//#include + +/* A representation of a double as a union. */ +union ieee754_double +{ + double d; + + /* This is the IEEE 754 double-precision format. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + } ieee_nan; +}; + +/* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +/* #if __FLOAT_WORD_ORDER == BIG_ENDIAN */ +/* #warning USING Big Endian float word order */ +/* typedef union */ +/* { */ +/* double value; */ +/* struct */ +/* { */ +/* u_int16_t msw; */ +/* u_int16_t lsw; */ +/* } parts; */ +/* } ieeeDoubleShapeType; */ + +/* #endif */ + +/* #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN */ +/* #warning USING Little Endian float word order */ + +typedef union +{ + double value; + struct + { + u_int16_t lsw; + u_int16_t msw; + } parts; +} ieeeDoubleShapeType; + +/* #endif */ + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +{ \ + ieeeDoubleShapeType ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +{ \ + ieeeDoubleShapeType iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + u_int32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +{ \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +{ \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} + + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/all_pairs/source/fmref/wcclibm.c b/all_pairs/source/fmref/wcclibm.c new file mode 100644 index 0000000..39b8cbe --- /dev/null +++ b/all_pairs/source/fmref/wcclibm.c @@ -0,0 +1,522 @@ +#include "math_private.h" +#include "wcclibm.h" + + + +/* e_rem_pio2f.c -- float version of e_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_rem_pio2f.c,v 1.5 1995/05/10 20:46:03 jtc Exp $"; +#endif + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2f() + */ + +/* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ +#ifdef __STDC__ +static const int32_t fmref_npio2_hw[] = { +#else +static int32_t fmref_npio2_hw[] = { +#endif +0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, +0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, +0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, +0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, +0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, +0x4242c700, 0x42490f00 +}; + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const float +#else +static float +#endif +/* zero = 0.0000000000e+00f, /\* 0x00000000 *\/ */ +/* half = 5.0000000000e-01f, /\* 0x3f000000 *\/ */ +/* two8 = 2.5600000000e+02f, /\* 0x43800000 *\/ */ +fmref_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ +fmref_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ +fmref_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ +fmref_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ +fmref_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ +fmref_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ +fmref_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + +#ifdef __STDC__ + int32_t fmref___ieee754_rem_pio2f(float x, float *y) +#else + int32_t fmref___ieee754_rem_pio2f(x,y) + float x,y[]; +#endif +{ + float z,w,t,r,fn; + int32_t i,j,n,ix,hx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - fmref_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - fmref_pio2_1t; + y[1] = (z-y[0])-fmref_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= fmref_pio2_2; + y[0] = z - fmref_pio2_2t; + y[1] = (z-y[0])-fmref_pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + fmref_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + fmref_pio2_1t; + y[1] = (z-y[0])+fmref_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += fmref_pio2_2; + y[0] = z + fmref_pio2_2t; + y[1] = (z-y[0])+fmref_pio2_2t; + } + return -1; + } + } + if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (int32_t) (t*fmref_invpio2+fmref_half); + fn = (float)n; + r = t-fn*fmref_pio2_1; + w = fn*fmref_pio2_1t; /* 1st round good to 40 bit */ + if(n<32&&(int32_t)(ix&0xffffff00)!=fmref_npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix>>23; + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*fmref_pio2_2; + r = t-w; + w = fn*fmref_pio2_2t-((t-r)-w); + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*fmref_pio2_3; + r = t-w; + w = fn*fmref_pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7f800000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + + y[0]=y[1]=x-x; /* dummy initialization */ + return 0; /* doesn't happen for our input */ +} + +/* k_cosf.c -- float version of k_cos.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_cosf.c,v 1.4 1995/05/10 20:46:23 jtc Exp $"; +#endif + + +#ifdef __STDC__ +static const float +#else +static float +#endif +/* one = 1.0000000000e+00, /\* 0x3f800000 *\/ */ +fmref_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ +fmref_C2 = -1.3888889225e-03f, /* 0xbab60b61 */ +fmref_C3 = 2.4801587642e-05f, /* 0x37d00d01 */ +fmref_C4 = -2.7557314297e-07f, /* 0xb493f27c */ +fmref_C5 = 2.0875723372e-09f, /* 0x310f74f6 */ +fmref_C6 = -1.1359647598e-11f; /* 0xad47d74e */ + +#ifdef __STDC__ + float fmref___kernel_cosf(float x, float y) +#else + float fmref___kernel_cosf(x, y) + float x,y; +#endif +{ + float a,hz,z,r,qx; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x32000000) { /* if x < 2**27 */ + if(((int)x)==0) return fmref_one; /* generate inexact */ + } + z = x*x; + r = z*(fmref_C1+z*(fmref_C2+z*(fmref_C3+z*(fmref_C4+z*(fmref_C5+z*fmref_C6))))); + if(ix < 0x3e99999a) /* if |x| < 0.3 */ + return fmref_one - ((float)0.5f*z - (z*r - x*y)); + else { + if(ix > 0x3f480000) { /* x > 0.78125 */ + qx = (float)0.28125f; + } else { + SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ + } + hz = (float)0.5f*z-qx; + a = fmref_one-qx; + return a - (hz - (z*r-x*y)); + } +} + +/* k_sinf.c -- float version of k_sin.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4 1995/05/10 20:46:33 jtc Exp $"; +#endif + + +#ifdef __STDC__ +static const float +#else +static float +#endif +/* half = 5.0000000000e-01f,/\* 0x3f000000 *\/ */ +fmref_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ +fmref_S2 = 8.3333337680e-03f, /* 0x3c088889 */ +fmref_S3 = -1.9841270114e-04f, /* 0xb9500d01 */ +fmref_S4 = 2.7557314297e-06f, /* 0x3638ef1b */ +fmref_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ +fmref_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ + +#ifdef __STDC__ + float fmref___kernel_sinf(float x, float y, int iy) +#else + float fmref___kernel_sinf(x, y, iy) + float x,y; int iy; /* iy=0 if y is zero */ +#endif +{ + float z,r,v; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x32000000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = fmref_S2+z*(fmref_S3+z*(fmref_S4+z*(fmref_S5+z*fmref_S6))); + if(iy==0) return x+v*(fmref_S1+z*r); + else return x-((z*(fmref_half*y-v*r)-y)-v*fmref_S1); +} +/* s_atanf.c -- float version of s_atan.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_atanf.c,v 1.4 1995/05/10 20:46:47 jtc Exp $"; +#endif + + +#ifdef __STDC__ +static const float fmref_atanhi[] = { +#else +static float fmref_atanhi[] = { +#endif + 4.6364760399e-01f, /* atan(0.5)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ +}; + +#ifdef __STDC__ +static const float fmref_atanlo[] = { +#else +static float fmref_atanlo[] = { +#endif + 5.0121582440e-09f, /* atan(0.5)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ +}; + +#ifdef __STDC__ +static const float fmref_aT[] = { +#else +static float fmref_aT[] = { +#endif + 3.3333334327e-01f, /* 0x3eaaaaaa */ + -2.0000000298e-01f, /* 0xbe4ccccd */ + 1.4285714924e-01f, /* 0x3e124925 */ + -1.1111110449e-01f, /* 0xbde38e38 */ + 9.0908870101e-02f, /* 0x3dba2e6e */ + -7.6918758452e-02f, /* 0xbd9d8795 */ + 6.6610731184e-02f, /* 0x3d886b35 */ + -5.8335702866e-02f, /* 0xbd6ef16b */ + 4.9768779427e-02f, /* 0x3d4bda59 */ + -3.6531571299e-02f, /* 0xbd15a221 */ + 1.6285819933e-02f, /* 0x3c8569d7 */ +}; + +/* #ifdef __STDC__ */ +/* static const float */ +/* #else */ +/* static float */ +/* #endif */ +/* one = 1.0, */ +/* huge = 1.0e30; */ + +#ifdef __STDC__ + float fmref___atanf(float x) +#else + float fmref___atanf(x) + float x; +#endif +{ + float w,s1,s2,z; + int32_t ix,hx,id; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x50800000) { /* if |x| >= 2^34 */ + if(ix>0x7f800000) + return x+x; /* NaN */ + if(hx>0) return fmref_atanhi[3]+fmref_atanlo[3]; + else return -fmref_atanhi[3]-fmref_atanlo[3]; + } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ + if (ix < 0x31000000) { /* |x| < 2^-29 */ + if(fmref_huge+x>fmref_one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsf(x); + if (ix < 0x3f980000) { /* |x| < 1.1875 */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = ((float)2.0f*x-fmref_one)/((float)2.0f+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-fmref_one)/(x+fmref_one); + } + } else { + if (ix < 0x401c0000) { /* |x| < 2.4375 */ + id = 2; x = (x-(float)1.5f)/(fmref_one+(float)1.5f*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -(float)1.0f/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(fmref_aT[0]+w*(fmref_aT[2]+w*(fmref_aT[4]+w*(fmref_aT[6]+w*(fmref_aT[8]+w*fmref_aT[10]))))); + s2 = w*(fmref_aT[1]+w*(fmref_aT[3]+w*(fmref_aT[5]+w*(fmref_aT[7]+w*fmref_aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = fmref_atanhi[id] - ((x*(s1+s2) - fmref_atanlo[id]) - x); + return (hx<0)? -z:z; + } +} +//weak_alias (__atanf, atanf) + +/* s_cosf.c -- float version of s_cos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* #ifdef __STDC__ */ +/* static const float one=1.0; */ +/* #else */ +/* static float one=1.0; */ +/* #endif */ + +#ifdef __STDC__ + float fmref___cosf(float x) +#else + float fmref___cosf(x) + float x; +#endif +{ + float y[2],z=0.0f; + int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return fmref___kernel_cosf(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = fmref___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return fmref___kernel_cosf(y[0],y[1]); + case 1: return -fmref___kernel_sinf(y[0],y[1],1); + case 2: return -fmref___kernel_cosf(y[0],y[1]); + default: + return fmref___kernel_sinf(y[0],y[1],1); + } + } +} + +/* s_sinf.c -- float version of s_sin.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + #ifdef __STDC__ + float fmref___sinf(float x) +#else + float fmref___sinf(x) + float x; +#endif +{ + float y[2],z=0.0; + int32_t n, ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return fmref___kernel_sinf(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = fmref___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return fmref___kernel_sinf(y[0],y[1],1); + case 1: return fmref___kernel_cosf(y[0],y[1]); + case 2: return -fmref___kernel_sinf(y[0],y[1],1); + default: + return -fmref___kernel_cosf(y[0],y[1]); + } + } +} + +/* s_fabsf.c -- float version of s_fabs.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabsf(x) returns the absolute value of x. + */ + + +#ifdef __STDC__ + float fmref___fabsf(float x) +#else + float fmref___fabsf(x) + float x; +#endif +{ + u_int32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} diff --git a/all_pairs/source/fmref/wcclibm.h b/all_pairs/source/fmref/wcclibm.h new file mode 100644 index 0000000..c00738b --- /dev/null +++ b/all_pairs/source/fmref/wcclibm.h @@ -0,0 +1,54 @@ +#ifndef _WCCLIBM +#define _WCCLIBM + +#define size_x unsigned long +#define int32_t int +#define uint32_t unsigned int +#define u_int16_t unsigned short +#define u_int32_t unsigned int + +// Often used variables/consts +#ifdef __STDC__ +static const float +#else +static float +#endif +fmref_one = 1.0f, +fmref_half = 5.0000000000e-01f, /* 0x3f000000 */ +fmref_zero = 0.0f, +fmref_huge = 1.0e30, +fmref_two8 = 2.5600000000e+02f, /* 0x43800000 */ +fmref_twon8 = 3.9062500000e-03f; /* 0x3b800000 */ + +// The following defines map the math functions to specialized calls +#define acos fmref___ieee754_acosf +#define atan fmref___atanf +#define cos fmref___cosf +#define fabs fmref___fabsf +#define fabsf fmref___fabsf +#define isinf fmref___isinff +#define pow fmref___ieee754_powf +#define sqrt fmref___ieee754_sqrtf +#define log10 fmref___ieee754_log10f +#define log fmref___ieee754_logf +#define sin fmref___sinf + +float fmref___atanf(float x); +float fmref___copysignf(float x, float y); +float fmref___cosf(float x); +float fmref___fabsf(float x); +float fmref___floorf(float x); +float fmref___ieee754_acosf(float x); +float fmref___ieee754_powf(float x, float y); +int32_t fmref___ieee754_rem_pio2f(float x, float *y); +float fmref___ieee754_sqrtf(float x); +int fmref___isinff (float x); +float fmref___kernel_cosf(float x, float y); +float fmref___kernel_sinf(float x, float y, int iy); +int fmref___kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2); +float fmref___scalbnf (float x, int n); +float fmref___ieee754_logf(float x); +float fmref___ieee754_log10f(float x); +float fmref___sinf(float x); + +#endif // _WCCLIBM diff --git a/all_pairs/source/g723_enc/ChangeLog.txt b/all_pairs/source/g723_enc/ChangeLog.txt new file mode 100644 index 0000000..8657026 --- /dev/null +++ b/all_pairs/source/g723_enc/ChangeLog.txt @@ -0,0 +1,34 @@ +File: g723_enc.c +Original provenience: SUN Microsystems + +2016-03-02: + - Renamed file to g723_enc and removed all g721 dead code + - Added TACLeBench header to line 1 + - Moved SUN license to license.txt + - Deleted unused code that was commented out + - Renamed functions prepended g723_enc to all function names + - Renamed function main to g723_enc_main + - Created new function main, calling g723_enc_init, g723_enc_main and + returning g723_enc_return + - Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions + - Applied code formatting with astyle as in the example + + 2016-03-09: + - Renamed global variables, prepended g723_enc_ + - Removed static keyword from global variables + - Renamed datatype from g723_enc_g72x_state to g723_enc_state + - Renamed function g723_enc_g72x_init_state to g723_enc_init_state + + 2016-05-23: + - Added initialization with volatile int + - Added check_sum and comparison with expected result + +2016-05-25 + - Changed name of struct g723_enc_state to g723_enc_state_t + - Changed name of variable state to g723_enc_state + +2017-07-10 + - Fixed undefined behaviour introduced by accessing the result of a pointer + type cast. diff --git a/all_pairs/source/g723_enc/g723_enc.c b/all_pairs/source/g723_enc/g723_enc.c new file mode 100644 index 0000000..6f31210 --- /dev/null +++ b/all_pairs/source/g723_enc/g723_enc.c @@ -0,0 +1,887 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: g723_enc + + Author: Unknown + + Function: g723 encoder. + + Source: SUN Microsystems + + Changes: The benchmark was changed to use the g723 encoder + + License: "Unrestricted use" (see license.txt) + +*/ + +/* + Declaration of data types +*/ + +/* + The following is the definition of the state structure + used by the G.721/G.723 encoder and decoder to preserve their internal + state between successive calls. The meanings of the majority + of the state structure fields are explained in detail in the + CCITT Recommendation G.721. The field names are essentially indentical + to variable names in the bit level description of the coding algorithm + included in this Recommendation. +*/ + +#include "../extra.h" +struct g723_enc_state_t { + long yl; /* Locked or steady state step size multiplier. */ + short yu; /* Unlocked or non-steady state step size multiplier. */ + short dms; /* Short term energy estimate. */ + short dml; /* Long term energy estimate. */ + short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ + + short a[2]; /* Coefficients of pole portion of prediction filter. */ + short b[6]; /* Coefficients of zero portion of prediction filter. */ + short pk[2]; /* + Signs of previous two samples of a partially + reconstructed signal. +*/ + short dq[6]; /* + Previous 6 samples of the quantized difference + signal represented in an internal floating point + format. +*/ + short sr[2]; /* + Previous 2 samples of the quantized difference + signal represented in an internal floating point + format. +*/ + char td; /* delayed tone detect, new in 1988 version */ +}; + + +/* + Forward declaration of functions +*/ + +int g723_enc_abs( int num ); +void g723_enc_init_state( struct g723_enc_state_t *state_ptr ); +int g723_enc_predictor_zero( struct g723_enc_state_t *state_ptr ); +int g723_enc_fmult( int an, int srn ); +int g723_enc_predictor_pole( struct g723_enc_state_t *state_ptr ); +int g723_enc_step_size( struct g723_enc_state_t *state_ptr ); +int g723_enc_quantize( + int d, /* Raw difference signal sample */ + int y, /* Step size multiplier */ + short *table, /* quantization table */ + int size ); /* table size of short integers */ +int g723_enc_reconstruct( + int sign, /* 0 for non-negative value */ + int dqln, /* G.72x codeword */ + int y ); /* Step size multiplier */ +void g723_enc_update( + int code_size, /* distinguish 723_40 with others */ + int y, /* quantizer step size */ + int wi, /* scale factor multiplier */ + int fi, /* for long/short term energies */ + int dq, /* quantized prediction difference */ + int sr, /* reconstructed signal */ + int dqsez, /* difference from 2-pole predictor */ + struct g723_enc_state_t *state_ptr ); /* coder state pointer */ +int g723_enc_quan( + int val, + short *table, + int size ); +int g723_enc_search( + int val, + short *table, + int size ); +int g723_enc_alaw2linear( unsigned char a_val ); +int g723_enc_ulaw2linear( unsigned char u_val ); +int g723_enc_g723_24_encoder( + int sample, + int in_coding, + struct g723_enc_state_t *state_ptr ); +int g723_enc_pack_output( + unsigned char code, + int bits ); + +void g723_enc_init(); +int g723_enc_return(); +void g723_enc_main(); +//int main( void ); + +/* + Declaration of global variables +*/ + +struct g723_enc_state_t g723_enc_state; + +unsigned int g723_enc_INPUT[256] = { + 51, 17, 31, 53, 95, 17, 70, 22, 49, 12, 8, 39, 28, 37, 99, 54, + 77, 65, 77, 78, 83, 15, 63, 31, 35, 92, 52, 40, 61, 79, 94, 87, + 87, 68, 76, 58, 39, 35, 20, 83, 42, 46, 98, 12, 21, 96, 74, 41, + 78, 76, 96, 2, 32, 76, 24, 59, 4, 96, 32, 5, 44, 92, 57, 12, + 57, 25, 50, 23, 48, 41, 88, 43, 36, 38, 4, 16, 52, 70, 9, 40, + 78, 24, 34, 23, 30, 30, 89, 3, 65, 40, 68, 73, 94, 23, 84, 97, + 78, 43, 68, 81, 16, 28, 13, 87, 75, 21, 14, 29, 81, 22, 56, 72, + 19, 99, 25, 43, 76, 86, 90, 98, 39, 43, 12, 46, 24, 99, 65, 61, + 24, 45, 79, 7, 48, 15, 24, 95, 62, 99, 48, 80, 75, 38, 48, 53, + 9, 60, 35, 14, 78, 71, 45, 71, 9, 97, 55, 74, 58, 64, 78, 18, + 30, 28, 69, 29, 57, 42, 30, 44, 57, 49, 61, 42, 13, 25, 3, 98, + 11, 38, 65, 35, 55, 36, 57, 48, 16, 62, 17, 56, 29, 88, 84, 85, + 90, 60, 54, 16, 66, 69, 26, 10, 82, 19, 42, 35, 84, 13, 26, 17, + 48, 38, 50, 50, 35, 53, 12, 52, 61, 74, 56, 34, 80, 59, 26, 67, + 55, 79, 89, 89, 6, 80, 91, 65, 16, 30, 16, 28, 85, 54, 3, 20, + 2, 36, 62, 52, 55, 15, 83, 3, 2, 38, 62, 2, 63, 92, 37, 73 +}; + + + +unsigned int g723_enc_OUTPUT[256]; + +short g723_enc_power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, + 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000 + }; + + +/* + Maps G.723_24 code word to reconstructed scale factor normalized log + magnitude values. +*/ + +short g723_enc_qtab_723_24[3] = {8, 218, 331}; + +/* + Maps G.721 code word to reconstructed scale factor normalized log + magnitude values. +*/ +short g723_enc_dqlntab[16] = { -2048, 4, 135, 213, 273, 323, 373, 425, + 425, 373, 323, 273, 213, 135, 4, -2048 + }; + +/* Maps G.721 code word to log of scale factor multiplier. */ +short g723_enc_witab[16] = { -12, 18, 41, 64, 112, 198, 355, 1122, + 1122, 355, 198, 112, 64, 41, 18, -12 + }; +/* + Maps G.721 code words to a set of values whose long and short + term averages are computed and then compared to give an indication + how stationary (steady state) the signal is. +*/ +short g723_enc_fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, + 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0 + }; + + +/* + Declaration of macros +*/ + + +#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */ +#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */ +#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */ + +#define BIAS (0x84) /* Bias for linear code. */ + +#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ +#define QUANT_MASK (0xf) /* Quantization field mask. */ +#define SEG_SHIFT (4) /* Left shift for segment number. */ +#define SEG_MASK (0x70) /* Segment field mask. */ + +/* + Arithmetic math functions +*/ + +/* + g723_enc_fmult() + + returns the integer product of the 14-bit integer "an" and + "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". +*/ +int g723_enc_fmult( + int an, + int srn ) +{ + short anmag, anexp, anmant; + short wanexp, wanmant; + short retval; + + anmag = ( an > 0 ) ? an : ( ( -an ) & 0x1FFF ); + anexp = g723_enc_quan( anmag, g723_enc_power2, 3 ) - 6; + anmant = ( anmag == 0 ) ? 32 : + ( anexp >= 0 ) ? anmag >> anexp : anmag << -anexp; + wanexp = anexp + ( ( srn >> 6 ) & 0xF ) - 13; + + wanmant = ( anmant * ( srn & 077 ) + 0x30 ) >> 4; + retval = ( wanexp >= 0 ) ? ( ( wanmant << wanexp ) & 0x7FFF ) : + ( wanmant >> -wanexp ); + + return ( ( ( an ^ srn ) < 0 ) ? -retval : retval ); +} + + +/* Manish Verma */ +int g723_enc_abs( int num ) +{ + return ( num < 0 ) ? -num : num; +} + + +/* + Algorithm core functions +*/ + + +/* + g723_enc_quan() + + quantizes the input val against the table of size short integers. + It returns i if table[i - 1] <= val < table[i]. + + Using linear search for simple coding. +*/ +int g723_enc_quan( + int val, + short *table, + int size ) +{ + int i, + j = 0, + k = 1; + + _Pragma( "loopbound min 3 max 15" ) + for ( i = 0; i < size; ++i ) { + + if ( k ) { + if ( val < *table++ ) { + j = i; + k = 0; + } + } + } + + return ( j ); +} + + +/* + g723_enc_predictor_zero() + + computes the estimated signal from 6-zero predictor. + +*/ +int +g723_enc_predictor_zero( + struct g723_enc_state_t *state_ptr ) +{ + int i; + int sezi; + + sezi = g723_enc_fmult( state_ptr->b[0] >> 2, state_ptr->dq[0] ); + _Pragma( "loopbound min 5 max 5" ) + for ( i = 1; i < 6; i++ ) /* ACCUM */ + sezi += g723_enc_fmult( state_ptr->b[i] >> 2, state_ptr->dq[i] ); + + return ( sezi ); +} + + +/* + g723_enc_predictor_pole() + + computes the estimated signal from 2-pole predictor. + +*/ +int +g723_enc_predictor_pole( + struct g723_enc_state_t *state_ptr ) +{ + return ( g723_enc_fmult( state_ptr->a[1] >> 2, state_ptr->sr[1] ) + + g723_enc_fmult( state_ptr->a[0] >> 2, state_ptr->sr[0] ) ); +} + +/* + g723_enc_step_size() + + computes the quantization step size of the adaptive quantizer. + +*/ +int +g723_enc_step_size( + struct g723_enc_state_t *state_ptr ) +{ + int y; + int dif; + int al; + + if ( state_ptr->ap >= 256 ) + return ( state_ptr->yu ); + else { + y = state_ptr->yl >> 6; + dif = state_ptr->yu - y; + al = state_ptr->ap >> 2; + if ( dif > 0 ) + y += ( dif * al ) >> 6; + else + if ( dif < 0 ) + y += ( dif * al + 0x3F ) >> 6; + + return ( y ); + } +} + +/* + g723_enc_quantize() + + Given a raw sample, 'd', of the difference signal and a + quantization step size scale factor, 'y', this routine returns the + ADPCM codeword to which that sample gets quantized. The step + size scale factor division operation is done in the log base 2 domain + as a subtraction. +*/ +int +g723_enc_quantize( + int d, /* Raw difference signal sample */ + int y, /* Step size multiplier */ + short *table, /* quantization table */ + int size ) /* table size of short integers */ +{ + short dqm; /* Magnitude of 'd' */ + short exp; /* Integer part of base 2 log of 'd' */ + short mant; /* Fractional part of base 2 log */ + short dl; /* Log of magnitude of 'd' */ + short dln; /* Step size scale factor normalized log */ + int i; + + /* + LOG + + Compute base 2 log of 'd', and store in 'dl'. + */ + dqm = g723_enc_abs( d ); + exp = g723_enc_quan( dqm >> 1, g723_enc_power2, 15 ); + mant = ( ( dqm << 7 ) >> exp ) & 0x7F; /* Fractional portion. */ + dl = ( exp << 7 ) + mant; + + /* + SUBTB + + "Divide" by step size multiplier. + */ + dln = dl - ( y >> 2 ); + + /* + QUAN + + Obtain codword i for 'd'. + */ + i = g723_enc_quan( dln, table, size ); + + if ( d < 0 ) /* take 1's complement of i */ + return ( ( size << 1 ) + 1 - i ); + else + if ( i == 0 ) /* take 1's complement of 0 */ + return ( ( size << 1 ) + 1 ); /* new in 1988 */ + else + return ( i ); +} +/* + g723_enc_reconstruct() + + Returns reconstructed difference signal 'dq' obtained from + codeword 'i' and quantization step size scale factor 'y'. + Multiplication is performed in log base 2 domain as addition. +*/ +int +g723_enc_reconstruct( + int sign, /* 0 for non-negative value */ + int dqln, /* G.72x codeword */ + int y ) /* Step size multiplier */ +{ + short dql; /* Log of 'dq' magnitude */ + short dex; /* Integer part of log */ + short dqt; + short dq; /* Reconstructed difference signal sample */ + + dql = dqln + ( y >> 2 ); /* ADDA */ + + if ( dql < 0 ) + return ( ( sign ) ? -0x8000 : 0 ); + else { /* ANTILOG */ + dex = ( dql >> 7 ) & 15; + dqt = 128 + ( dql & 127 ); + dq = ( dqt << 7 ) >> ( 14 - dex ); + return ( ( sign ) ? ( dq - 0x8000 ) : dq ); + } +} + + +/* + g723_enc_update() + + updates the state variables for each output code +*/ +void +g723_enc_update( + int code_size, /* distinguish 723_40 with others */ + int y, /* quantizer step size */ + int wi, /* scale factor multiplier */ + int fi, /* for long/short term energies */ + int dq, /* quantized prediction difference */ + int sr, /* reconstructed signal */ + int dqsez, /* difference from 2-pole predictor */ + struct g723_enc_state_t *state_ptr ) /* coder state pointer */ +{ + int cnt; + short mag, exp; /* Adaptive predictor, FLOAT A */ + short a2p; /* LIMC */ + short a1ul; /* UPA1 */ + short pks1; /* UPA2 */ + short fa1; + char tr; /* tone/transition detector */ + short ylint, thr2, dqthr; + short ylfrac, thr1; + short pk0; + + pk0 = ( dqsez < 0 ) ? 1 : 0; /* needed in updating predictor poles */ + + mag = dq & 0x7FFF; /* prediction difference magnitude */ + /* TRANS */ + ylint = state_ptr->yl >> 15; /* exponent part of yl */ + ylfrac = ( state_ptr->yl >> 10 ) & 0x1F; /* fractional part of yl */ + thr1 = ( 32 + ylfrac ) << ylint; /* threshold */ + thr2 = ( ylint > 9 ) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ + dqthr = ( thr2 + ( thr2 >> 1 ) ) >> 1; /* dqthr = 0.75 * thr2 */ + if ( state_ptr->td == 0 ) /* signal supposed voice */ + tr = 0; + else + if ( mag <= dqthr ) /* supposed data, but small mag */ + tr = 0; /* treated as voice */ + else /* signal is data (modem) */ + tr = 1; + + /* + Quantizer scale factor adaptation. + */ + + /* FUNCTW & FILTD & DELAY */ + /* update non-steady state step size multiplier */ + state_ptr->yu = y + ( ( wi - y ) >> 5 ); + + /* LIMB */ + if ( state_ptr->yu < 544 ) /* 544 <= yu <= 5120 */ + state_ptr->yu = 544; + else + if ( state_ptr->yu > 5120 ) + state_ptr->yu = 5120; + + /* FILTE & DELAY */ + /* update steady state step size multiplier */ + state_ptr->yl += state_ptr->yu + ( ( -state_ptr->yl ) >> 6 ); + + /* + Adaptive predictor coefficients. + */ + if ( tr == 1 ) { /* reset a's and b's for modem signal */ + state_ptr->a[0] = 0; + state_ptr->a[1] = 0; + state_ptr->b[0] = 0; + state_ptr->b[1] = 0; + state_ptr->b[2] = 0; + state_ptr->b[3] = 0; + state_ptr->b[4] = 0; + state_ptr->b[5] = 0; + } else { /* update a's and b's */ + pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ + + /* update predictor pole a[1] */ + a2p = state_ptr->a[1] - ( state_ptr->a[1] >> 7 ); + if ( dqsez != 0 ) { + fa1 = ( pks1 ) ? state_ptr->a[0] : -state_ptr->a[0]; + if ( fa1 < -8191 ) /* a2p = function of fa1 */ + a2p -= 0x100; + else + if ( fa1 > 8191 ) + a2p += 0xFF; + else + a2p += fa1 >> 5; + if ( pk0 ^ state_ptr->pk[1] ) + /* LIMC */ + if ( a2p <= -12160 ) + a2p = -12288; + else + if ( a2p >= 12416 ) + a2p = 12288; + else + a2p -= 0x80; + else + if ( a2p <= -12416 ) + a2p = -12288; + else + if ( a2p >= 12160 ) + a2p = 12288; + else + a2p += 0x80; + + } + + /* TRIGB & DELAY */ + state_ptr->a[1] = a2p; + + /* UPA1 */ + /* update predictor pole a[0] */ + state_ptr->a[0] -= state_ptr->a[0] >> 8; + if ( dqsez != 0 ) { + if ( pks1 == 0 ) + state_ptr->a[0] += 192; + else + state_ptr->a[0] -= 192; + } + + /* LIMD */ + a1ul = 15360 - a2p; + if ( state_ptr->a[0] < -a1ul ) + state_ptr->a[0] = -a1ul; + else + if ( state_ptr->a[0] > a1ul ) + state_ptr->a[0] = a1ul; + + /* UPB : update predictor zeros b[6] */ + _Pragma( "loopbound min 6 max 6" ) + for ( cnt = 0; cnt < 6; cnt++ ) { + if ( code_size == 5 ) /* for 40Kbps G.723 */ + state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9; + else /* for G.721 and 24Kbps G.723 */ + state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; + if ( dq & 0x7FFF ) { /* XOR */ + if ( ( dq ^ state_ptr->dq[cnt] ) >= 0 ) + state_ptr->b[cnt] += 128; + else + state_ptr->b[cnt] -= 128; + } + + } + } + + _Pragma( "loopbound min 5 max 5" ) + for ( cnt = 5; cnt > 0; cnt-- ) + state_ptr->dq[cnt] = state_ptr->dq[cnt - 1]; + /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ + if ( mag == 0 ) + state_ptr->dq[0] = ( dq >= 0 ) ? 0x20 : 0xFC20; + else { + exp = g723_enc_quan( mag, g723_enc_power2, 15 ); + state_ptr->dq[0] = ( dq >= 0 ) ? + ( exp << 6 ) + ( ( mag << 6 ) >> exp ) : + ( exp << 6 ) + ( ( mag << 6 ) >> exp ) - 0x400; + + } + + state_ptr->sr[1] = state_ptr->sr[0]; + /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ + if ( sr == 0 ) + state_ptr->sr[0] = 0x20; + else + if ( sr > 0 ) { + exp = g723_enc_quan( sr, g723_enc_power2, 15 ); + state_ptr->sr[0] = ( exp << 6 ) + ( ( sr << 6 ) >> exp ); + } else + if ( sr > -32768 ) { + mag = -sr; + exp = g723_enc_quan( mag, g723_enc_power2, 15 ); + state_ptr->sr[0] = ( exp << 6 ) + ( ( mag << 6 ) >> exp ) - 0x400; + } else + state_ptr->sr[0] = 0xFC20; + + /* DELAY A */ + state_ptr->pk[1] = state_ptr->pk[0]; + state_ptr->pk[0] = pk0; + + /* TONE */ + if ( tr == 1 ) /* this sample has been treated as data */ + state_ptr->td = 0; /* next one will be treated as voice */ + else + if ( a2p < -11776 ) /* small sample-to-sample correlation */ + state_ptr->td = 1; /* signal may be data */ + else /* signal is voice */ + state_ptr->td = 0; + + /* + Adaptation speed control. + */ + state_ptr->dms += ( fi - state_ptr->dms ) >> 5; /* FILTA */ + state_ptr->dml += ( ( ( fi << 2 ) - state_ptr->dml ) >> 7 ); /* FILTB */ + + if ( tr == 1 ) + state_ptr->ap = 256; + else + if ( y < 1536 ) /* SUBTC */ + state_ptr->ap += ( 0x200 - state_ptr->ap ) >> 4; + else + if ( state_ptr->td == 1 ) + state_ptr->ap += ( 0x200 - state_ptr->ap ) >> 4; + else + if ( g723_enc_abs( ( state_ptr->dms << 2 ) - state_ptr->dml ) >= + ( state_ptr->dml >> 3 ) ) + state_ptr->ap += ( 0x200 - state_ptr->ap ) >> 4; + else + state_ptr->ap += ( -state_ptr->ap ) >> 4; + +} + + +/* + g723_enc_alaw2linear() - Convert an A-law value to 16-bit linear PCM + +*/ +int +g723_enc_alaw2linear( + unsigned char a_val ) +{ + int t; + int seg; + + a_val ^= 0x55; + + t = ( a_val & QUANT_MASK ) << 4; + seg = ( ( unsigned )a_val & SEG_MASK ) >> SEG_SHIFT; + switch ( seg ) { + case 0: + t += 8; + break; + case 1: + t += 0x108; + break; + default: + t += 0x108; + t <<= seg - 1; + } + return ( ( a_val & SIGN_BIT ) ? t : -t ); +} + + +/* + g723_enc_ulaw2linear() - Convert a u-law value to 16-bit linear PCM + + First, a biased linear code is derived from the code word. An unbiased + output can then be obtained by subtracting 33 from the biased code. + + Note that this function expects to be passed the complement of the + original code word. This is in keeping with ISDN conventions. +*/ +int +g723_enc_ulaw2linear( + unsigned char u_val ) +{ + int t; + + /* Complement to obtain normal u-law value. */ + u_val = ~u_val; + + /* + Extract and bias the quantization bits. Then + shift up by the segment number and subtract out the bias. + */ + t = ( ( u_val & QUANT_MASK ) << 3 ) + BIAS; + t <<= ( ( unsigned int )u_val & SEG_MASK ) >> SEG_SHIFT; + + return ( ( u_val & SIGN_BIT ) ? ( BIAS - t ) : ( t - BIAS ) ); +} + + +/* + g723_enc_g723_24_encoder() + + Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. + Returns -1 if invalid input coding value. +*/ +int +g723_enc_g723_24_encoder( + int sl, + int in_coding, + struct g723_enc_state_t *state_ptr ) +{ + short sei, sezi, se, sez; /* ACCUM */ + short d; /* SUBTA */ + short y; /* MIX */ + short sr; /* ADDB */ + short dqsez; /* ADDC */ + short dq, i; + + switch ( in_coding ) { /* linearize input sample to 14-bit PCM */ + case AUDIO_ENCODING_ALAW: + sl = g723_enc_alaw2linear( sl ) >> 2; + break; + case AUDIO_ENCODING_ULAW: + sl = g723_enc_ulaw2linear( sl ) >> 2; + break; + case AUDIO_ENCODING_LINEAR: + sl >>= 2; /* sl of 14-bit dynamic range */ + break; + default: + return ( -1 ); + } + + sezi = g723_enc_predictor_zero( state_ptr ); + sez = sezi >> 1; + sei = sezi + g723_enc_predictor_pole( state_ptr ); + se = sei >> 1; /* se = estimated signal */ + + d = sl - se; /* d = estimation diff. */ + + /* quantize prediction difference d */ + y = g723_enc_step_size( state_ptr ); /* quantizer step size */ + i = g723_enc_quantize( d, y, g723_enc_qtab_723_24, 3 ); /* i = ADPCM code */ + dq = g723_enc_reconstruct( i & 4, g723_enc_dqlntab[i], y ); /* quantized diff. */ + + sr = ( dq < 0 ) ? se - ( dq & 0x3FFF ) : se + dq; /* reconstructed signal */ + + dqsez = sr + sez - se; /* pole prediction diff. */ + + g723_enc_update( 3, y, g723_enc_witab[i], g723_enc_fitab[i], dq, sr, dqsez, state_ptr ); + + return ( i ); +} + +/* + Pack output codes into bytes and write them to stdout. + Returns 1 if there is residual output, else returns 0. +*/ +int +g723_enc_pack_output( + unsigned char code, + int bits ) +{ + static unsigned int out_buffer = 0; + static int out_bits = 0; + unsigned char out_byte; + static int i = 0; + + out_buffer |= ( code << out_bits ); + out_bits += bits; + if ( out_bits >= 8 ) { + out_byte = out_buffer & 0xff; + out_bits -= 8; + out_buffer >>= 8; + //fwrite(&out_byte, sizeof (char), 1, fp_out); + //fwrite(&out_byte, 1, 1, fp_out); + g723_enc_OUTPUT[i] = out_byte; + i = i + 1; + } + + return ( out_bits > 0 ); +} + +/* + Initialization- and return-value-related functions +*/ + +/* + g723_enc_init_state() + + This routine initializes and/or resets the g72x_state structure + pointed to by 'state_ptr'. + All the initial state values are specified in the CCITT G.721 document. +*/ +void +g723_enc_init_state( + struct g723_enc_state_t *state_ptr ) +{ + int cnta; + + state_ptr->yl = 34816; + state_ptr->yu = 544; + state_ptr->dms = 0; + state_ptr->dml = 0; + state_ptr->ap = 0; + + _Pragma( "loopbound min 2 max 2" ) + for ( cnta = 0; cnta < 2; cnta++ ) { + state_ptr->a[cnta] = 0; + state_ptr->pk[cnta] = 0; + state_ptr->sr[cnta] = 32; + } + _Pragma( "loopbound min 6 max 6" ) + for ( cnta = 0; cnta < 6; cnta++ ) { + state_ptr->b[cnta] = 0; + state_ptr->dq[cnta] = 32; + } + state_ptr->td = 0; +} + + +void g723_enc_init() +{ + int i; + volatile int x = 0; + g723_enc_init_state( &g723_enc_state ); + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + g723_enc_INPUT[i] += x; + } +} + + +int g723_enc_return() +{ + int i; + int check_sum = 0; + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + check_sum += g723_enc_OUTPUT[i]; + } + + return ( check_sum != 24284 ); +} + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) g723_enc_main() +{ +// struct g72x_state state; + short sample_short; //mv + unsigned char code; + int resid; + int in_coding; + short *in_buf; + int enc_bits; + int i = 0; + + enc_bits = 3; + in_coding = AUDIO_ENCODING_ALAW; + in_buf = &sample_short; + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + *in_buf = g723_enc_INPUT[i]; + code = g723_enc_g723_24_encoder( sample_short, in_coding, &g723_enc_state ); + resid = g723_enc_pack_output( code, enc_bits ); + } + + /* Write zero codes until all residual codes are written out */ + _Pragma( "loopbound min 0 max 0" ) + while ( resid ) + resid = g723_enc_pack_output( 0, enc_bits ); +} + + +int main( int argc, char **argv ) +{ + //SET_UP + int jobsComplete; + int maxJobs=9; + for (jobsComplete=-1; jobsComplete= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ + ? MAX_LONGWORD : utmp)) + +/* + # define GSM_ADD(a, b) \ + ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) +*/ +/* Nonportable, but faster: */ + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +#define saturate(x) \ + ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) + +/* Use these if necessary: + + # define GSM_MULT_R(a, b) gsm_mult_r(a, b) + # define GSM_MULT(a, b) gsm_mult(a, b) + # define GSM_L_MULT(a, b) gsm_L_mult(a, b) + + # define GSM_L_ADD(a, b) gsm_L_add(a, b) + # define GSM_ADD(a, b) gsm_add(a, b) + # define GSM_SUB(a, b) gsm_sub(a, b) + + # define GSM_ABS(a) gsm_abs(a) + +*/ + +#endif /* GSM_DEC_ADD_H */ diff --git a/all_pairs/source/gsm_dec/data.h b/all_pairs/source/gsm_dec/data.h new file mode 100644 index 0000000..81bf20d --- /dev/null +++ b/all_pairs/source/gsm_dec/data.h @@ -0,0 +1,865 @@ +#ifndef GSM_DEC_DATA_H +#define GSM_DEC_DATA_H + +gsm_signal gsm_dec_pcmdata[] = { + ( short )0x0000, ( short )0x0000, ( short )0x0010, ( short )0x0010, + ( short )0x0010, ( short )0x0020, ( short )0x0020, ( short )0x0018, + ( short )0x0028, ( short )0x0020, ( short )0x0020, ( short )0x0028, + ( short )0x0028, ( short )0x0020, ( short )0x0030, ( short )0x0030, + ( short )0x0028, ( short )0x0010, ( short )0x0008, ( short )0x0000, + ( short )0x0050, ( short )0x0060, ( short )0x0058, ( short )0x00D0, + ( short )0x00E0, ( short )0x00D0, ( short )0x0118, ( short )0x0128, + ( short )0x0118, ( short )0x0128, ( short )0x0110, ( short )0x0100, + ( short )0x00A0, ( short )0x0058, ( short )0x0048, ( short )0x0058, + ( short )0x0060, ( short )0x0058, ( short )0x0050, ( short )0x0048, + ( short )0x0040, ( short )0x0030, ( short )0x0020, ( short )0x0010, + ( short )0x0008, ( short )0xFFF8, ( short )0xFFE8, ( short )0xFFE0, + ( short )0xFFD8, ( short )0xFFC8, ( short )0xFFC0, ( short )0xFFC0, + ( short )0xFF98, ( short )0xFF78, ( short )0xFF78, ( short )0xFFC8, + ( short )0x0000, ( short )0x0010, ( short )0x0040, ( short )0x0060, + ( short )0x0068, ( short )0x0078, ( short )0x0078, ( short )0x0070, + ( short )0x00A8, ( short )0x00C8, ( short )0x00C8, ( short )0x00E0, + ( short )0x00F0, ( short )0x00E8, ( short )0x00F8, ( short )0x00F8, + ( short )0x00F0, ( short )0x00E0, ( short )0x00C8, ( short )0x00B8, + ( short )0x00E8, ( short )0x0100, ( short )0x00F8, ( short )0x00E8, + ( short )0x00D8, ( short )0x00C0, ( short )0x00A8, ( short )0x0020, + ( short )0xFFC0, ( short )0xFFA0, ( short )0xFFA0, ( short )0xFFA8, + ( short )0xFFB0, ( short )0xFFD0, ( short )0xFFF8, ( short )0x0000, + ( short )0x0020, ( short )0x0030, ( short )0x0030, ( short )0x0030, + ( short )0x0028, ( short )0x0020, ( short )0xFFF0, ( short )0xFFD0, + ( short )0xFFC8, ( short )0xFFC8, ( short )0xFFD0, ( short )0xFFD8, + ( short )0xFFE8, ( short )0xFFF8, ( short )0xFFF8, ( short )0x0008, + ( short )0x0018, ( short )0x0018, ( short )0x0078, ( short )0x00B8, + ( short )0x00C0, ( short )0x0100, ( short )0x0130, ( short )0x0128, + ( short )0x0108, ( short )0x00D8, ( short )0x00C0, ( short )0x0078, + ( short )0x0038, ( short )0x0020, ( short )0x0020, ( short )0x0000, + ( short )0xFFE0, ( short )0xFFE0, ( short )0xFFD8, ( short )0xFFC8, + ( short )0xFFC8, ( short )0xFFA0, ( short )0xFF88, ( short )0xFF98, + ( short )0xFF80, ( short )0xFF70, ( short )0xFF80, ( short )0xFF78, + ( short )0xFF78, ( short )0xFF90, ( short )0xFF80, ( short )0xFF78, + ( short )0xFF78, ( short )0xFF50, ( short )0xFF30, ( short )0xFF50, + ( short )0xFF38, ( short )0xFF30, ( short )0xFF40, ( short )0xFF58, + ( short )0xFF70, ( short )0xFF80, ( short )0xFF50, ( short )0xFF38, + ( short )0xFF40, ( short )0xFF18, ( short )0xFF00, ( short )0xFF08, + ( short )0xFF40, ( short )0xFF68, ( short )0xFF80, ( short )0xFF88, + ( short )0xFF88, ( short )0xFF88, ( short )0xFF88, ( short )0xFFB8, + ( short )0xFFE0, ( short )0xFFF0, ( short )0xFFD0, ( short )0xFFB8, + ( short )0xFFB8, ( short )0xFF90, ( short )0xFF70, ( short )0xFF70, + ( short )0xFF50, ( short )0xFF40, ( short )0xFF40, ( short )0xFF58, + ( short )0xFF70, ( short )0xFF80, ( short )0xFFC8, ( short )0x0000, + ( short )0x0018, ( short )0x0030, ( short )0x0048, ( short )0x0048, + ( short )0x0028, ( short )0x0008, ( short )0xFFF8, ( short )0xFFD8, + ( short )0xFFC8, ( short )0xFFB8, ( short )0xFF98, ( short )0xFF78, + ( short )0xFF70, ( short )0xFFF0, ( short )0x0058, ( short )0x0088, + ( short )0x00B8, ( short )0x00D0, ( short )0x00D8, ( short )0x00E8, + ( short )0x0138, ( short )0x0160, ( short )0x0158, ( short )0x0170, + ( short )0x0178, ( short )0x0160, ( short )0x0168, ( short )0x0160, + ( short )0x0140, ( short )0x0118, ( short )0x00F0, ( short )0x00C8, + ( short )0x0098, ( short )0x0078, ( short )0x0060, ( short )0x0018, + ( short )0xFFC0, ( short )0xFF90, ( short )0xFF48, ( short )0xFF00, + ( short )0xFEE8, ( short )0xFEC8, ( short )0xFEB8, ( short )0xFEB8, + ( short )0xFEA0, ( short )0xFE88, ( short )0xFE80, ( short )0xFEB8, + ( short )0xFEF8, ( short )0xFF38, ( short )0xFFA0, ( short )0xFFE8, + ( short )0x0008, ( short )0x0030, ( short )0x0058, ( short )0x0068, + ( short )0x0068, ( short )0x0070, ( short )0x0068, ( short )0x0050, + ( short )0x0040, ( short )0x0040, ( short )0x0020, ( short )0x0000, + ( short )0xFFE8, ( short )0xFFF0, ( short )0xFFF8, ( short )0xFFF8, + ( short )0x0038, ( short )0x0068, ( short )0x0078, ( short )0x0038, + ( short )0x0008, ( short )0xFFF0, ( short )0xFFE0, ( short )0xFFD8, + ( short )0xFFD8, ( short )0xFFE0, ( short )0xFFD0, ( short )0xFFC8, + ( short )0x0000, ( short )0x0030, ( short )0x0048, ( short )0x0068, + ( short )0x0080, ( short )0x0088, ( short )0x0088, ( short )0x0088, + ( short )0x0088, ( short )0x0088, ( short )0x0088, ( short )0x0078, + ( short )0x0098, ( short )0x00B0, ( short )0x00B8, ( short )0x0098, + ( short )0x0070, ( short )0x0058, ( short )0x0060, ( short )0x0078, + ( short )0x00A8, ( short )0x00B8, ( short )0x00A8, ( short )0x00A0, + ( short )0x0080, ( short )0x0068, ( short )0x0060, ( short )0x0058, + ( short )0x0048, ( short )0x0030, ( short )0x0038, ( short )0x0038, + ( short )0x0030, ( short )0x0050, ( short )0x0058, ( short )0x0060, + ( short )0x0030, ( short )0x0008, ( short )0xFFF8, ( short )0xFF90, + ( short )0xFF48, ( short )0xFF28, ( short )0xFF10, ( short )0xFEF8, + ( short )0xFEF0, ( short )0xFED8, ( short )0xFEB0, ( short )0xFEB0, + ( short )0xFEA8, ( short )0xFEB8, ( short )0xFED8, ( short )0xFEF8, + ( short )0xFF10, ( short )0xFF20, ( short )0xFF40, ( short )0xFF58, + ( short )0xFF80, ( short )0xFFA0, ( short )0xFFB8, ( short )0xFFC8, + ( short )0xFFD8, ( short )0xFFE0, ( short )0xFFF0, ( short )0x0048, + ( short )0x0098, ( short )0x00B0, ( short )0x0068, ( short )0x0018, + ( short )0xFFF8, ( short )0xFFE8, ( short )0xFFF0, ( short )0xFFF8, + ( short )0x0020, ( short )0x0038, ( short )0x0038, ( short )0x0050, + ( short )0x0068, ( short )0x0070, ( short )0x0068, ( short )0x0060, + ( short )0x0060, ( short )0x0038, ( short )0x0020, ( short )0x0018, + ( short )0x0040, ( short )0x0060, ( short )0x0068, ( short )0x0040, + ( short )0x0010, ( short )0x0000, ( short )0xFFB0, ( short )0xFF78, + ( short )0xFF70, ( short )0xFF90, ( short )0xFFA8, ( short )0xFFC8, + ( short )0xFF98, ( short )0xFF50, ( short )0xFF50, ( short )0xFF50, + ( short )0xFF58, ( short )0xFF68, ( short )0xFF48, ( short )0xFF20, + ( short )0xFF18, ( short )0xFF38, ( short )0xFF60, ( short )0xFF70, + ( short )0xFF80, ( short )0xFF98, ( short )0xFFA0, ( short )0xFFB8, + ( short )0xFFD0, ( short )0xFFE0, ( short )0x0018, ( short )0x0048, + ( short )0x0058, ( short )0x00B0, ( short )0x00F8, ( short )0x0108, + ( short )0x0118, ( short )0x0120, ( short )0x0118, ( short )0x0130, + ( short )0x0148, ( short )0x0140, ( short )0x0130, ( short )0x0120, + ( short )0x0108, ( short )0x0098, ( short )0x0038, ( short )0x0018, + ( short )0xFFD0, ( short )0xFF90, ( short )0xFF80, ( short )0xFF58, + ( short )0xFF38, ( short )0xFF30, ( short )0xFF48, ( short )0xFF68, + ( short )0xFF78, ( short )0xFF88, ( short )0xFFB8, ( short )0xFFD8, + ( short )0xFFE8, ( short )0xFFD8, ( short )0xFFF0, ( short )0x0010, + ( short )0x0020, ( short )0x0020, ( short )0x0018, ( short )0x0028, + ( short )0x0030, ( short )0x0030, ( short )0x0038, ( short )0x0060, + ( short )0x0080, ( short )0x0080, ( short )0x00B0, ( short )0x00D8, + ( short )0x00D0, ( short )0x00B8, ( short )0x00A8, ( short )0x00A8, + ( short )0x00A0, ( short )0x0090, ( short )0x0078, ( short )0x0070, + ( short )0x0068, ( short )0x0048, ( short )0x0018, ( short )0x0008, + ( short )0x0008, ( short )0x0000, ( short )0x0000, ( short )0xFFE8, + ( short )0xFFB0, ( short )0xFF90, ( short )0xFF88, ( short )0xFF70, + ( short )0xFF60, ( short )0xFF60, ( short )0xFF90, ( short )0xFFC0, + ( short )0xFFD0, ( short )0xFFD8, ( short )0xFFE0, ( short )0xFFE8, + ( short )0x0018, ( short )0x0050, ( short )0x0058, ( short )0x0030, + ( short )0x0008, ( short )0x0000, ( short )0x0018, ( short )0x0038, + ( short )0x0038, ( short )0x0048, ( short )0x0050, ( short )0x0050, + ( short )0x0020, ( short )0x0000, ( short )0xFFF8, ( short )0xFFB0, + ( short )0xFF70, ( short )0xFF68, ( short )0xFFB0, ( short )0xFFE8, + ( short )0xFFF8, ( short )0xFFF8, ( short )0xFFF8, ( short )0xFFF0, + ( short )0x0030, ( short )0x0070, ( short )0x0090, ( short )0x0098, + ( short )0x0098, ( short )0x0090, ( short )0x00A0, ( short )0x00B0, + ( short )0x00B8, ( short )0x00C0, ( short )0x00C0, ( short )0x00A8, + ( short )0x0098, ( short )0x0088, ( short )0x0078, ( short )0x0050, + ( short )0x0030, ( short )0x0020, ( short )0xFFD8, ( short )0xFF98, + ( short )0xFF88, ( short )0xFF50, ( short )0xFF20, ( short )0xFF18, + ( short )0xFEF8, ( short )0xFEE0, ( short )0xFEE8, ( short )0xFE70, + ( short )0xFE08, ( short )0xFE00, ( short )0xFE48, ( short )0xFE98, + ( short )0xFEB8, ( short )0xFEE8, ( short )0xFF10, ( short )0xFF28, + ( short )0xFF18, ( short )0xFF10, ( short )0xFF18, ( short )0xFF48, + ( short )0xFF70, ( short )0xFF88, ( short )0xFFE0, ( short )0x0028, + ( short )0x0040, ( short )0x0058, ( short )0x0068, ( short )0x0070, + ( short )0x0078, ( short )0x0070, ( short )0x0068, ( short )0x0068, + ( short )0x0078, ( short )0x0080, ( short )0x0080, ( short )0x0088, + ( short )0x0088, ( short )0x0080, ( short )0x0058, ( short )0x0030, + ( short )0x0020, ( short )0x0018, ( short )0x0018, ( short )0x0018, + ( short )0x0050, ( short )0x0090, ( short )0x00A0, ( short )0x0080, + ( short )0x0060, ( short )0x0050, ( short )0x0030, ( short )0x0018, + ( short )0x0010, ( short )0x0028, ( short )0x0038, ( short )0x0038, + ( short )0x0018, ( short )0xFFF8, ( short )0xFFF0, ( short )0x0000, + ( short )0x0020, ( short )0x0020, ( short )0x0030, ( short )0x0030, + ( short )0x0030, ( short )0x0040, ( short )0x0050, ( short )0x0050, + ( short )0x0050, ( short )0x0048, ( short )0x0048, ( short )0x0048, + ( short )0x0048, ( short )0x0048, ( short )0x0078, ( short )0x00A0, + ( short )0x00A8, ( short )0x00C0, ( short )0x00C8, ( short )0x00C0, + ( short )0x00D0, ( short )0x00E0, ( short )0x00D8, ( short )0x00E8, + ( short )0x00F0, ( short )0x00E0, ( short )0x0100, ( short )0x0118, + ( short )0x0110, ( short )0x0100, ( short )0x00F0, ( short )0x00D8, + ( short )0x0090, ( short )0x0048, ( short )0x0028, ( short )0x0020, + ( short )0x0020, ( short )0x0020, ( short )0x0038, ( short )0x0050, + ( short )0x0050, ( short )0x0050, ( short )0x0048, ( short )0x0040, + ( short )0x0050, ( short )0x0060, ( short )0x0060, ( short )0x0040, + ( short )0xFFC0, ( short )0xFF58, ( short )0xFF40, ( short )0xFF90, + ( short )0xFFE8, ( short )0x0000, ( short )0x0020, ( short )0x0030, + ( short )0x0030, ( short )0x0068, ( short )0x0098, ( short )0x00A8, + ( short )0x0110, ( short )0x0168, ( short )0x0170, ( short )0x0148, + ( short )0x0118, ( short )0x00F0, ( short )0x00E8, ( short )0x00E0, + ( short )0x00D0, ( short )0x0098, ( short )0x0060, ( short )0x0040, + ( short )0x0000, ( short )0xFFD8, ( short )0xFFD8, ( short )0xFFC0, + ( short )0xFFB0, ( short )0xFFB0, ( short )0xFF78, ( short )0xFF30, + ( short )0xFF10, ( short )0xFEF0, ( short )0xFEE8, ( short )0xFEF0, + ( short )0xFEC8, ( short )0xFED0, ( short )0xFEF8, ( short )0xFF00, + ( short )0xFF10, ( short )0xFF20, ( short )0xFF50, ( short )0xFF78, + ( short )0xFF90, ( short )0xFF80, ( short )0xFF70, ( short )0xFF70, + ( short )0xFF80, ( short )0xFF98, ( short )0xFFA0, ( short )0xFFB8, + ( short )0xFFD0, ( short )0xFFD8, ( short )0xFFF0, ( short )0x0000, + ( short )0x0008, ( short )0x0028, ( short )0x0048, ( short )0x0058, + ( short )0x0078, ( short )0x0070, ( short )0x0058, ( short )0x0068, + ( short )0x0098, ( short )0x00B8, ( short )0x00D8, ( short )0x00F0, + ( short )0x00F0, ( short )0x00E8, ( short )0x00F8, ( short )0x0100, + ( short )0x00D8, ( short )0x00D0, ( short )0x00C8, ( short )0x00E8, + ( short )0x0100, ( short )0x00F0, ( short )0x00E0, ( short )0x00C8, + ( short )0x00B8, ( short )0x00A0, ( short )0x0078, ( short )0x0058, + ( short )0x0038, ( short )0x0020, ( short )0x0010, ( short )0x0010, + ( short )0x0018, ( short )0x0010, ( short )0x0010, ( short )0x0010, + ( short )0x0018, ( short )0x0028, ( short )0x0008, ( short )0xFFE0, + ( short )0xFFC8, ( short )0xFF80, ( short )0xFF48, ( short )0xFF38, + ( short )0xFF40, ( short )0xFF48, ( short )0xFF48, ( short )0xFF70, + ( short )0xFF90, ( short )0xFFA8, ( short )0xFFB8, ( short )0xFFC0, + ( short )0xFFC8, ( short )0xFFC0, ( short )0xFFC0, ( short )0xFFC0, + ( short )0xFFB0, ( short )0xFFA0, ( short )0xFFA0, ( short )0xFFA0, + ( short )0xFFA8, ( short )0xFFB0, ( short )0xFF68, ( short )0xFF28, + ( short )0xFF08, ( short )0xFEF8, ( short )0xFEF8, ( short )0xFEE8, + ( short )0xFEE0, ( short )0xFED8, ( short )0xFEA8, ( short )0xFE98, + ( short )0xFEA8, ( short )0xFEA8, ( short )0xFEA0, ( short )0xFEA0, + ( short )0xFED0, ( short )0xFF00, ( short )0xFF30, ( short )0xFF28, + ( short )0xFF38, ( short )0xFF58, ( short )0xFF48, ( short )0xFF40, + ( short )0xFF48, ( short )0xFFB0, ( short )0x0010, ( short )0x0038, + ( short )0x0028, ( short )0x0010, ( short )0x0008, ( short )0x0050, + ( short )0x00A0, ( short )0x00B8, ( short )0x00A0, ( short )0x0080, + ( short )0x0070, ( short )0x0090, ( short )0x00B0, ( short )0x00B0, + ( short )0x00B8, ( short )0x00B8, ( short )0x00B0, ( short )0x00C0, + ( short )0x00D0, ( short )0x00C8, ( short )0x00A0, ( short )0x0068, + ( short )0x0038, ( short )0xFFF0, ( short )0xFFB0, ( short )0xFF88, + ( short )0xFF78, ( short )0xFF68, ( short )0xFF60, ( short )0xFF90, + ( short )0xFFC0, ( short )0xFFE0, ( short )0x0000, ( short )0x0020, + ( short )0x0030, ( short )0x00A0, ( short )0x0110, ( short )0x0138, + ( short )0x0140, ( short )0x0148, ( short )0x0148, ( short )0x0110, + ( short )0x00E8, ( short )0x00C0, ( short )0x00A0, ( short )0x0088, + ( short )0x0068, ( short )0x0008, ( short )0xFFB0, ( short )0xFF88, + ( short )0xFF58, ( short )0xFF30, ( short )0xFF20, ( short )0xFEF8, + ( short )0xFED8, ( short )0xFED8, ( short )0xFF00, ( short )0xFF20, + ( short )0xFF38, ( short )0xFF50, ( short )0xFF68, ( short )0xFF88, + ( short )0xFFA0, ( short )0xFFB8, ( short )0x0020, ( short )0x0080, + ( short )0x00A0, ( short )0x00D8, ( short )0x0100, ( short )0x0100, + ( short )0x0138, ( short )0x0168, ( short )0x0148, ( short )0x0128, + ( short )0x0120, ( short )0x00F8, ( short )0x00E8, ( short )0x00E0, + ( short )0x00C0, ( short )0x00A8, ( short )0x00B0, ( short )0x0098, + ( short )0x0070, ( short )0x0048, ( short )0x0030, ( short )0xFFD0, + ( short )0xFF60, ( short )0xFF48, ( short )0xFF10, ( short )0xFEA8, + ( short )0xFEA8, ( short )0xFEC0, ( short )0xFEC0, ( short )0xFEE8, + ( short )0xFEB0, ( short )0xFE58, ( short )0xFE88, ( short )0xFED0, + ( short )0xFEB8, ( short )0xFE48, ( short )0xFE58, ( short )0xFEE8, + ( short )0xFF28, ( short )0xFF18, ( short )0xFF60, ( short )0x00A0, + ( short )0x01A0, ( short )0x0188, ( short )0x0178, ( short )0x0208, + ( short )0x0208, ( short )0x0100, ( short )0x0018, ( short )0xFFE0, + ( short )0xFEE0, ( short )0xFD68, ( short )0xFD00, ( short )0xFD60, + ( short )0xFD70, ( short )0xFDA8, ( short )0xFF00, ( short )0x00A0, + ( short )0x0170, ( short )0x0210, ( short )0x02D8, ( short )0x0310, + ( short )0x0218, ( short )0x00A0, ( short )0xFFA0, ( short )0xFDF0, + ( short )0xFBD8, ( short )0xFB08, ( short )0xF9C0, ( short )0xF830, + ( short )0xF8D8, ( short )0xFCC0, ( short )0x0038, ( short )0x01A0, + ( short )0x0380, ( short )0x0A18, ( short )0x0F50, ( short )0x0DB0, + ( short )0x0C30, ( short )0x0E18, ( short )0x0CA8, ( short )0x0570, + ( short )0xFF98, ( short )0xFE38, ( short )0xFBA0, ( short )0xF700, + ( short )0xF5D0, ( short )0xF7C8, ( short )0xF9A8, ( short )0xFB48, + ( short )0xFBB0, ( short )0xFC78, ( short )0xFF00, ( short )0xFE98, + ( short )0xFB20, ( short )0xFA48, ( short )0xFAC0, ( short )0xF8C8, + ( short )0xF6E0, ( short )0xF9C0, ( short )0xFE08, ( short )0xFF80, + ( short )0x0428, ( short )0x0B70, ( short )0x0E18, ( short )0x0D38, + ( short )0x0D38, ( short )0x0C28, ( short )0x01D0, ( short )0xF578, + ( short )0xF108, ( short )0xFB50, ( short )0x0498, ( short )0x0428, + ( short )0x0CE8, ( short )0x2190, ( short )0x29F0, ( short )0x22E0, + ( short )0x1F68, ( short )0x2050, ( short )0x1810, ( short )0x0710, + ( short )0xFA98, ( short )0xF438, ( short )0xEE68, ( short )0xE950, + ( short )0xEBC8, ( short )0xF538, ( short )0xFEB8, ( short )0x0240, + ( short )0x0460, ( short )0x09D0, ( short )0x0978, ( short )0xFFF8, + ( short )0xF810, ( short )0xF190, ( short )0xE8D0, ( short )0xE290, + ( short )0xDF60, ( short )0xDFF0, ( short )0xE668, ( short )0xEC20, + ( short )0xF138, ( short )0xFAC0, ( short )0x04F0, ( short )0x08D0, + ( short )0x08C8, ( short )0x0B18, ( short )0x09F8, ( short )0x0230, + ( short )0xFA38, ( short )0xFA68, ( short )0xFC78, ( short )0xF9B8, + ( short )0xF850, ( short )0xFEA8, ( short )0x05B8, ( short )0x0690, + ( short )0x02E8, ( short )0x0268, ( short )0x0498, ( short )0xFCB0, + ( short )0xF018, ( short )0xEDF8, ( short )0x0090, ( short )0x0F48, + ( short )0x0C70, ( short )0x1278, ( short )0x27B8, ( short )0x2EA0, + ( short )0x21F8, ( short )0x1920, ( short )0x1918, ( short )0x1530, + ( short )0x0638, ( short )0xF858, ( short )0xF720, ( short )0xF9F8, + ( short )0xF600, ( short )0xF850, ( short )0x0590, ( short )0x0EE0, + ( short )0x1000, ( short )0x10D8, ( short )0x1460, ( short )0x10F8, + ( short )0x0500, ( short )0xFBC0, ( short )0xF7A8, ( short )0xF250, + ( short )0xEC00, ( short )0xEB30, ( short )0xF1C8, ( short )0xF920, + ( short )0xFC90, ( short )0x0190, ( short )0x0A60, ( short )0x0E80, + ( short )0x0DB0, ( short )0x0AD8, ( short )0x0690, ( short )0x0168, + ( short )0xFF20, ( short )0xFBD0, ( short )0xF6F8, ( short )0xF660, + ( short )0xF680, ( short )0xF5B0, ( short )0xF7C0, ( short )0xF120, + ( short )0xEA90, ( short )0xF030, ( short )0xEC18, ( short )0xE190, + ( short )0xE558, ( short )0xFF20, ( short )0x1090, ( short )0x0C50, + ( short )0x1248, ( short )0x2788, ( short )0x2AD0, ( short )0x1628, + ( short )0x08F0, ( short )0x0BA8, ( short )0x0538, ( short )0xEF48, + ( short )0xE410, ( short )0xEB10, ( short )0xEF68, ( short )0xEA28, + ( short )0xEC40, ( short )0xFC18, ( short )0x08A8, ( short )0x0818, + ( short )0x0778, ( short )0x0858, ( short )0x02F8, ( short )0xF8E8, + ( short )0xF1F0, ( short )0xEF40, ( short )0xECD0, ( short )0xE958, + ( short )0xEA70, ( short )0xF260, ( short )0xFAF0, ( short )0xFFA0, + ( short )0x04A0, ( short )0x0CF8, ( short )0x10F8, ( short )0x0EA0, + ( short )0x0D48, ( short )0x0BE8, ( short )0x05E0, ( short )0x03B0, + ( short )0x0358, ( short )0xFF18, ( short )0xFB40, ( short )0xF9B0, + ( short )0xF9C0, ( short )0xF7C0, ( short )0xEE90, ( short )0xEAA0, + ( short )0xEE00, ( short )0xE888, ( short )0xE200, ( short )0xEF00, + ( short )0x0948, ( short )0x1400, ( short )0x1270, ( short )0x1D88, + ( short )0x2CD8, ( short )0x2488, ( short )0x0DA8, ( short )0x04B8, + ( short )0x0548, ( short )0xF7B0, ( short )0xE3F0, ( short )0xE268, + ( short )0xEFF8, ( short )0xF5A0, ( short )0xF320, ( short )0xFC68, + ( short )0x0BF0, ( short )0x0FA0, ( short )0x0A50, ( short )0x01F8, + ( short )0xFE60, ( short )0xFC48, ( short )0xF340, ( short )0xEB28, + ( short )0xED58, ( short )0xF3C0, ( short )0xF5B8, ( short )0xF738, + ( short )0x00F8, ( short )0x0C70, ( short )0x0E90, ( short )0x0DE8, + ( short )0x1190, ( short )0x12B0, ( short )0x1058, ( short )0x0B98, + ( short )0x0638, ( short )0x0868, ( short )0x0998, ( short )0x02B0, + ( short )0xFE50, ( short )0x0120, ( short )0x02A0, ( short )0xFC90, + ( short )0xF810, ( short )0xF9D0, ( short )0xF818, ( short )0xF290, + ( short )0xF240, ( short )0xF6D0, ( short )0x0A48, ( short )0x1AD8, + ( short )0x1840, ( short )0x1C18, ( short )0x2B18, ( short )0x29F0, + ( short )0x1608, ( short )0x08B8, ( short )0x0778, ( short )0x0128, + ( short )0xF118, ( short )0xE868, ( short )0xEDA0, ( short )0xF310, + ( short )0xF248, ( short )0xF558, ( short )0x0058, ( short )0x0970, + ( short )0x0688, ( short )0x0108, ( short )0xFD08, ( short )0xF988, + ( short )0xF558, ( short )0xF0A0, ( short )0xF0B0, ( short )0xF540, + ( short )0xF6E8, ( short )0xFCA0, ( short )0x0758, ( short )0x0CD0, + ( short )0x0F60, ( short )0x1338, ( short )0x1458, ( short )0x1278, + ( short )0x0FD0, ( short )0x0CA8, ( short )0x0D50, ( short )0x0D10, + ( short )0x0798, ( short )0x0398, ( short )0x0428, ( short )0x04F0, + ( short )0x0278, ( short )0xFF98, ( short )0x0178, ( short )0x0088, + ( short )0xFB08, ( short )0xF660, ( short )0xF1A8, ( short )0xEF18, + ( short )0xF9E8, ( short )0x0C00, ( short )0x11C8, ( short )0x1260, + ( short )0x1B60, ( short )0x21B0, ( short )0x18E0, ( short )0x0B08, + ( short )0x04C8, ( short )0x0078, ( short )0xF730, ( short )0xEF60, + ( short )0xEB18, ( short )0xEC10, ( short )0xF290, ( short )0xF800, + ( short )0xFB60, ( short )0xFF60, ( short )0x0080, ( short )0xFFA8, + ( short )0xFB08, ( short )0xF1A8, ( short )0xED10, ( short )0xEFF0, + ( short )0xEED0, ( short )0xEB10, ( short )0xEFE8, ( short )0xF8F0, + ( short )0xFDE0, ( short )0x0298, ( short )0x0528, ( short )0x0598, + ( short )0x0928, ( short )0x0A30, ( short )0x0670, ( short )0x08E8, + ( short )0x0BC0, ( short )0x0698, ( short )0x0210, ( short )0x0390, + ( short )0x0560, ( short )0x0288, ( short )0xF910, ( short )0xF468, + ( short )0xF560, ( short )0xF3E0, ( short )0xEE10, ( short )0xE8B0, + ( short )0xE508, ( short )0xEED0, ( short )0x03E0, ( short )0x0638, + ( short )0xFFA8, ( short )0x0BB8, ( short )0x2078, ( short )0x1FA8, + ( short )0x0EF0, ( short )0x0648, ( short )0x05C8, ( short )0xFF18, + ( short )0xF588, ( short )0xEE20, ( short )0xED88, ( short )0xF5A0, + ( short )0xFBA8, ( short )0xFBC0, ( short )0xFA98, ( short )0xFA20, + ( short )0xF7D8, ( short )0xF2D0, ( short )0xEF48, ( short )0xE998, + ( short )0xE378, ( short )0xE530, ( short )0xE868, ( short )0xE890, + ( short )0xEDD0, ( short )0xF798, ( short )0xFBC0, ( short )0xFD20, + ( short )0x0178, ( short )0x0490, ( short )0x04A0, ( short )0x0758, + ( short )0x0858, ( short )0x0490, ( short )0x04F8, ( short )0x0858, + ( short )0x06F0, ( short )0x05F8, ( short )0x0450, ( short )0x0098, + ( short )0xFE60, ( short )0xFDA0, ( short )0xF9E0, ( short )0xF358, + ( short )0xEDC0, ( short )0xF308, ( short )0xFFE0, ( short )0x0018, + ( short )0xFB80, ( short )0x0948, ( short )0x1DB8, ( short )0x1D08, + ( short )0x0F88, ( short )0x0B48, ( short )0x0C50, ( short )0x09C0, + ( short )0xFF78, ( short )0xF1A0, ( short )0xEF28, ( short )0xF6B8, + ( short )0xF9F0, ( short )0xF6F0, ( short )0xF688, ( short )0xF9E0, + ( short )0xF9C0, ( short )0xF4C8, ( short )0xEBD8, ( short )0xE7E8, + ( short )0xEBE0, ( short )0xE8C8, ( short )0xE100, ( short )0xE518, + ( short )0xF0B8, ( short )0xF728, ( short )0xF770, ( short )0xF878, + ( short )0xFF58, ( short )0x06B0, ( short )0x0430, ( short )0x0060, + ( short )0x0390, ( short )0x0A18, ( short )0x0B98, ( short )0x06C8, + ( short )0x0710, ( short )0x0CF0, ( short )0x08D0, ( short )0x01F8, + ( short )0x0280, ( short )0x0238, ( short )0xFD78, ( short )0xF868, + ( short )0xF198, ( short )0xF670, ( short )0x0930, ( short )0x0A78, + ( short )0xFB38, ( short )0x04F0, ( short )0x1EB8, ( short )0x1E98, + ( short )0x0F68, ( short )0x0EC8, ( short )0x1548, ( short )0x1480, + ( short )0x0C60, ( short )0x00B0, ( short )0xFEF8, ( short )0x0830, + ( short )0x0838, ( short )0x0160, ( short )0x0380, ( short )0x07E8, + ( short )0x0270, ( short )0xFBA0, ( short )0xF9C0, ( short )0xF450, + ( short )0xEE08, ( short )0xED08, ( short )0xEE10, ( short )0xEF20, + ( short )0xF1C0, ( short )0xF800, ( short )0xFE70, ( short )0x00B0, + ( short )0x02D8, ( short )0x07C8, ( short )0x09F0, ( short )0x09A8, + ( short )0x0A60, ( short )0x0B28, ( short )0x0C80, ( short )0x0D58, + ( short )0x0BD0, ( short )0x0A48, ( short )0x0900, ( short )0x0768, + ( short )0x03D0, ( short )0x00E0, ( short )0xFFF8, ( short )0xFBD8, + ( short )0xF5E8, ( short )0xFE18, ( short )0x0FE8, ( short )0x1060, + ( short )0x05C8, ( short )0x1078, ( short )0x2638, ( short )0x2580, + ( short )0x1740, ( short )0x14E8, ( short )0x19D0, ( short )0x17D8, + ( short )0x0E10, ( short )0x0270, ( short )0x0120, ( short )0x0900, + ( short )0x0870, ( short )0x0290, ( short )0x03A0, ( short )0x0600, + ( short )0x0100, ( short )0xFE28, ( short )0xFF28, ( short )0xF838, + ( short )0xF0B8, ( short )0xF238, ( short )0xF530, ( short )0xF440, + ( short )0xF440, ( short )0xFA38, ( short )0x0198, ( short )0x03A8, + ( short )0x03D0, ( short )0x0780, ( short )0x0AB8, ( short )0x0B58, + ( short )0x0B10, ( short )0x0AD8, ( short )0x0A08, ( short )0x0878, + ( short )0x07C8, ( short )0x0648, ( short )0x01A0, ( short )0xFF48, + ( short )0xFE58, ( short )0xFA68, ( short )0xF7D0, ( short )0xF758, + ( short )0xF470, ( short )0xF5B0, ( short )0x02A8, ( short )0x0A58, + ( short )0x0448, ( short )0x07C8, ( short )0x1708, ( short )0x1970, + ( short )0x0EC8, ( short )0x0A40, ( short )0x0CD0, ( short )0x0D28, + ( short )0x0838, ( short )0x0010, ( short )0xFAE0, ( short )0xFCB0, + ( short )0xFEB8, ( short )0xFCE8, ( short )0xFBA8, ( short )0xFD10, + ( short )0xFBC8, ( short )0xF910, ( short )0xF960, ( short )0xF830, + ( short )0xF4D8, ( short )0xF500, ( short )0xF860, ( short )0xF9F0, + ( short )0xFB58, ( short )0xFE48, ( short )0x0050, ( short )0x0418, + ( short )0x0910, ( short )0x0940, ( short )0x0830, ( short )0x0AC8, + ( short )0x0C88, ( short )0x0A50, ( short )0x07C0, ( short )0x0700, + ( short )0x0590, ( short )0x0268, ( short )0xFFF0, ( short )0xFBA8, + ( short )0xF720, ( short )0xF698, ( short )0xF2E0, ( short )0xEB68, + ( short )0xEDA0, ( short )0xFC00, ( short )0x0358, ( short )0xFF30, + ( short )0x0398, ( short )0x1220, ( short )0x1860, ( short )0x1368, + ( short )0x10C0, ( short )0x12F0, ( short )0x12A0, ( short )0x0E08, + ( short )0x0780, ( short )0x0010, ( short )0xFAD8, ( short )0xF990, + ( short )0xF7E0, ( short )0xF278, ( short )0xEE10, ( short )0xEB98, + ( short )0xE7A0, ( short )0xE6F8, ( short )0xEA30, ( short )0xE980, + ( short )0xE420, ( short )0xE440, ( short )0xEBA8, ( short )0xEF98, + ( short )0xEF68, ( short )0xF288, ( short )0xF7A8, ( short )0xFC90, + ( short )0x01F8, ( short )0x0528, ( short )0x0630, ( short )0x08E8, + ( short )0x0C98, ( short )0x0D50, ( short )0x0B98, ( short )0x0920, + ( short )0x0678, ( short )0x03F0, ( short )0x0260, ( short )0xFE00, + ( short )0xF810, ( short )0xF4B8, ( short )0xF0C0, ( short )0xEB68, + ( short )0xEF58, ( short )0xFAE8, ( short )0xFDE0, ( short )0xF680, + ( short )0xF910, ( short )0x06E0, ( short )0x0C20, ( short )0x05D8, + ( short )0x0408, ( short )0x05C8, ( short )0x0450, ( short )0x02D0, + ( short )0x0128, ( short )0xFB78, ( short )0xF668, ( short )0xF430, + ( short )0xF150, ( short )0xED90, ( short )0xE870, ( short )0xE448, + ( short )0xE2E0, ( short )0xE048, ( short )0xDDD0, ( short )0xDF08, + ( short )0xE0E0, ( short )0xE098, ( short )0xE258, ( short )0xE520, + ( short )0xE6A8, ( short )0xEA28, ( short )0xEF88, ( short )0xF2A8, + ( short )0xF548, ( short )0xFBA8, ( short )0x01C8, ( short )0x03F8, + ( short )0x0748, ( short )0x0C88, ( short )0x0E98, ( short )0x0DB8, + ( short )0x0D98, ( short )0x0D50, ( short )0x0B68, ( short )0x0970, + ( short )0x06C0, ( short )0x0238, ( short )0xFE18, ( short )0xFB08, + ( short )0xF820, ( short )0xF780, ( short )0xF970, ( short )0xF9B0, + ( short )0xF880, ( short )0xFA28, ( short )0x0028, ( short )0x0698, + ( short )0x0948, ( short )0x08D0, ( short )0x09E0, ( short )0x0DD0, + ( short )0x1010, ( short )0x0D40, ( short )0x0958, ( short )0x0728, + ( short )0x0308, ( short )0xFDA0, ( short )0xF9F8, ( short )0xF418, + ( short )0xEC98, ( short )0xE8B8, ( short )0xE618, ( short )0xE200, + ( short )0xDED0, ( short )0xDF48, ( short )0xE100, ( short )0xE180, + ( short )0xE160, ( short )0xE3C8, ( short )0xE898, ( short )0xEDD8, + ( short )0xF250, ( short )0xF558, ( short )0xFB00, ( short )0x02F8, + ( short )0x07B0, ( short )0x0B80, ( short )0x1108, ( short )0x1518, + ( short )0x1660, ( short )0x1770, ( short )0x1870, ( short )0x16F8, + ( short )0x1300, ( short )0x0F78, ( short )0x0FC0, ( short )0x1070, + ( short )0x0CE8, ( short )0x0AF8, ( short )0x0BD8, ( short )0x0D28, + ( short )0x10A8, ( short )0x1370, ( short )0x10A0, ( short )0x1040, + ( short )0x1518, ( short )0x1740, ( short )0x1550, ( short )0x1398, + ( short )0x10E0, ( short )0x0AC8, ( short )0x0640, ( short )0x0348, + ( short )0xFD18, ( short )0xF658, ( short )0xF1D8, ( short )0xEC20, + ( short )0xE760, ( short )0xE550, ( short )0xE4B8, ( short )0xE418, + ( short )0xE438, ( short )0xE508, ( short )0xE738, ( short )0xEB18, + ( short )0xF0C8, ( short )0xF618, ( short )0xF988, ( short )0xFEC8, + ( short )0x0518, ( short )0x09D8, ( short )0x1118, ( short )0x17F0, + ( short )0x1BB0, ( short )0x1E28, ( short )0x2120, ( short )0x23D8, + ( short )0x2638, ( short )0x2418, ( short )0x2080, ( short )0x1D30, + ( short )0x1CE8, ( short )0x1D98, ( short )0x1CA8, ( short )0x1AD8, + ( short )0x1960, ( short )0x17F8, ( short )0x1A40, ( short )0x1CF8, + ( short )0x1D38, ( short )0x1C30, ( short )0x1A68, ( short )0x1860, + ( short )0x1480, ( short )0x1020, ( short )0x0B68, ( short )0x03E8, + ( short )0xFBA8, ( short )0xF508, ( short )0xEE40, ( short )0xE820, + ( short )0xE338, ( short )0xDE88, ( short )0xDA30, ( short )0xD7D0, + ( short )0xD728, ( short )0xD7D8, ( short )0xD998, ( short )0xDC10, + ( short )0xDFB0, ( short )0xE470, ( short )0xE948, ( short )0xEF98, + ( short )0xF5F0, ( short )0xFC38, ( short )0x0228, ( short )0x0798, + ( short )0x0D98, ( short )0x1320, ( short )0x1760, ( short )0x1A70, + ( short )0x1BE0, ( short )0x1CC0, ( short )0x1D98, ( short )0x1A88, + ( short )0x1658, ( short )0x12A0, ( short )0x1180, ( short )0x10A8, + ( short )0x0ED0, ( short )0x0CC8, ( short )0x0AD8, ( short )0x0920, + ( short )0x0B70, ( short )0x0E30, ( short )0x0EE8, ( short )0x0D80, + ( short )0x0BE0, ( short )0x0AC0, ( short )0x09B8, ( short )0x0890, + ( short )0x0690, ( short )0x01F8, ( short )0xFD30, ( short )0xF9F0, + ( short )0xF5B0, ( short )0xF188, ( short )0xEE38, ( short )0xE9E8, + ( short )0xE5E8, ( short )0xE3E0, ( short )0xE4A0, ( short )0xE608, + ( short )0xE738, ( short )0xE858, ( short )0xE980, ( short )0xEC20, + ( short )0xF030, ( short )0xF450, ( short )0xF878, ( short )0xFC68, + ( short )0xFF68, ( short )0x03C8, ( short )0x08B8, ( short )0x0D00, + ( short )0x1038, ( short )0x12D8, ( short )0x1490, ( short )0x1648, + ( short )0x16B8, ( short )0x1468, ( short )0x1160, ( short )0x0FA8, + ( short )0x1038, ( short )0x1058, ( short )0x0F88, ( short )0x0E50, + ( short )0x0CC8, ( short )0x0CC0, ( short )0x0FC0, ( short )0x1220, + ( short )0x12A0, ( short )0x10F8, ( short )0x0F20, ( short )0x0D28, + ( short )0x0C78, ( short )0x0BB8, ( short )0x08D0, ( short )0x01C8, + ( short )0xFB38, ( short )0xF660, ( short )0xF330, ( short )0xF078, + ( short )0xEC28, ( short )0xE6C8, ( short )0xE2C0, ( short )0xE050, + ( short )0xDFC8, ( short )0xE038, ( short )0xE160, ( short )0xE300, + ( short )0xE568, ( short )0xE6B8, ( short )0xE9A0, ( short )0xED50, + ( short )0xF238, ( short )0xF6D8, ( short )0xFB08, ( short )0xFF10, + ( short )0x02E8, ( short )0x06A0, ( short )0x0AC0, ( short )0x0DC8, + ( short )0x1010, ( short )0x1168, ( short )0x1018, ( short )0x0E90, + ( short )0x0BF8, ( short )0x0B08, ( short )0x0A50, ( short )0x09F0, + ( short )0x0960, ( short )0x0888, ( short )0x0808, ( short )0x09C8, + ( short )0x0BA8, ( short )0x0EE8, ( short )0x1070, ( short )0x10D0, + ( short )0x0F58, ( short )0x0D60, ( short )0x0BA0, ( short )0x0A60, + ( short )0x08F0, ( short )0x0608, ( short )0xFFB0, ( short )0xF938, + ( short )0xF360, ( short )0xF030, ( short )0xEE20, ( short )0xEB70, + ( short )0xE7A8, ( short )0xE410, ( short )0xE140, ( short )0xDFC8, + ( short )0xDFF8, ( short )0xE1F0, ( short )0xE448, ( short )0xE6D0, + ( short )0xE780, ( short )0xE9E8, ( short )0xECF0, ( short )0xF248, + ( short )0xF730, ( short )0xFBC0, ( short )0xFF80, ( short )0x0310, + ( short )0x0670, ( short )0x0A98, ( short )0x0D88, ( short )0x0FD8, + ( short )0x10C0, ( short )0x0EB0, ( short )0x0C48, ( short )0x08B8, + ( short )0x0998, ( short )0x0AC0, ( short )0x0C68, ( short )0x0B78, + ( short )0x09C8, ( short )0x0838, ( short )0x08F8, ( short )0x0A80, + ( short )0x0CA0, ( short )0x0E10, ( short )0x0E48, ( short )0x0D58, + ( short )0x0A28, ( short )0x0750, ( short )0x04F0, ( short )0x0228, + ( short )0xFEE8, ( short )0xFA80, ( short )0xF468, ( short )0xEED0, + ( short )0xEAE0, ( short )0xE8B8, ( short )0xE718, ( short )0xE5B0, + ( short )0xE4A8, ( short )0xE410, ( short )0xE480, ( short )0xE548, + ( short )0xE738, ( short )0xE9B0, ( short )0xED80, ( short )0xF0B8, + ( short )0xF480, ( short )0xF7B0, ( short )0xFB70, ( short )0xFED0, + ( short )0x0328, ( short )0x0720, ( short )0x0A98, ( short )0x0E00, + ( short )0x10F8, ( short )0x12E0, ( short )0x12A8, ( short )0x11B0, + ( short )0x0F58, ( short )0x0F38, ( short )0x0E88, ( short )0x0F08, + ( short )0x0FC0, ( short )0x0FF0, ( short )0x10B8, ( short )0x1138, + ( short )0x1198, ( short )0x13D0, ( short )0x1638, ( short )0x17E8, + ( short )0x1758, ( short )0x1628, ( short )0x1460, ( short )0x10E8, + ( short )0x0CA0, ( short )0x0848, ( short )0x0280, ( short )0xFC90, + ( short )0xF700, ( short )0xF0F8, ( short )0xEB18, ( short )0xE638, + ( short )0xE1B8, ( short )0xDE78, ( short )0xDC58, ( short )0xDBB8, + ( short )0xDC28, ( short )0xDDB0, ( short )0xE030, ( short )0xE330, + ( short )0xE6F0, ( short )0xEC20, ( short )0xF210, ( short )0xF7C0, + ( short )0xFCE0, ( short )0x0150, ( short )0x0570, ( short )0x08F0, + ( short )0x0C70, ( short )0x0F50, ( short )0x12B8, ( short )0x1560, + ( short )0x16E0, ( short )0x1630, ( short )0x14E8, ( short )0x1298, + ( short )0x11B8, ( short )0x1170, ( short )0x11B8, ( short )0x11C0, + ( short )0x0FE8, ( short )0x0E58, ( short )0x0CB8, ( short )0x0C50, + ( short )0x0D68, ( short )0x0E98, ( short )0x0E30, ( short )0x0C28, + ( short )0x0A10, ( short )0x06D8, ( short )0x02E0, ( short )0xFEA0, + ( short )0xFA18, ( short )0xF4E8, ( short )0xF018, ( short )0xEB68, + ( short )0xE6E8, ( short )0xE310, ( short )0xDFC8, ( short )0xDD38, + ( short )0xDBF8, ( short )0xDC38, ( short )0xDDD0, ( short )0xE070, + ( short )0xE390, ( short )0xE760, ( short )0xEB88, ( short )0xEF20, + ( short )0xF378, ( short )0xF830, ( short )0xFCE0, ( short )0x00F8, + ( short )0x0480, ( short )0x0768, ( short )0x0968, ( short )0x0AE0, + ( short )0x0BB8, ( short )0x0C10, ( short )0x0BB0, ( short )0x0A78, + ( short )0x08E0, ( short )0x06E8, ( short )0x0540, ( short )0x0870, + ( short )0x0BE0, ( short )0x0ED0, ( short )0x0E40, ( short )0x0D10, + ( short )0x0CC8, ( short )0x0E28, ( short )0x0FA0, ( short )0x0FB0, + ( short )0x0F18, ( short )0x0DD0, ( short )0x0BC8, ( short )0x08E8, + ( short )0x0628, ( short )0x0300, ( short )0xFF18, ( short )0xFB40, + ( short )0xF780, ( short )0xF388, ( short )0xF028, ( short )0xED80, + ( short )0xEB18, ( short )0xE968, ( short )0xE8C0, ( short )0xE738, + ( short )0xE658, ( short )0xE698, ( short )0xE888, ( short )0xEB38, + ( short )0xEDA0, ( short )0xF178, ( short )0xF5B8, ( short )0xFA28, + ( short )0xFEA8, ( short )0x0300, ( short )0x06C8, ( short )0x0960, + ( short )0x0B70, ( short )0x0CE0, ( short )0x0D70, ( short )0x0D50, + ( short )0x0C60, ( short )0x0890, ( short )0x0418, ( short )0x0028, + ( short )0x01D0, ( short )0x03F8, ( short )0x05A8, ( short )0x0700, + ( short )0x0808, ( short )0x09A0, ( short )0x0B18, ( short )0x0CC8, + ( short )0x0D90, ( short )0x0E68, ( short )0x0EC0, ( short )0x0E30, + ( short )0x0C28, ( short )0x09D8, ( short )0x0730, ( short )0x0308, + ( short )0xFED8, ( short )0xFAC0, ( short )0xF598, ( short )0xF0D8, + ( short )0xECE0, ( short )0xEAA8, ( short )0xE948, ( short )0xE8D0, + ( short )0xE850, ( short )0xE888, ( short )0xE910, ( short )0xEAD0, + ( short )0xED68, ( short )0xF018, ( short )0xF350, ( short )0xF6B8, + ( short )0xFAE0, ( short )0xFF00, ( short )0x02D8, ( short )0x05E8, + ( short )0x0830, ( short )0x09F8, ( short )0x0B08, ( short )0x0B80, + ( short )0x0B60, ( short )0x0988, ( short )0x0648, ( short )0x02D0, + ( short )0x0150, ( short )0x01E8, ( short )0x0270, ( short )0x03E0, + ( short )0x0538, ( short )0x0658, ( short )0x0918, ( short )0x0C00, + ( short )0x0E88, ( short )0x10B8, ( short )0x12A0, ( short )0x13E0, + ( short )0x1488, ( short )0x1448, ( short )0x1368, ( short )0x1120, + ( short )0x0DD0, ( short )0x0A40, ( short )0x0608, ( short )0x0148, + ( short )0xFC80, ( short )0xF860, ( short )0xF4D8, ( short )0xF1C0, + ( short )0xF008, ( short )0xEF38, ( short )0xEE78, ( short )0xEE98, + ( short )0xEF90, ( short )0xF170, ( short )0xF390, ( short )0xF5C0, + ( short )0xF888, ( short )0xFB48, ( short )0xFDF0, ( short )0x0078, + ( short )0x03D0, ( short )0x06C8, ( short )0x08F8, ( short )0x0AA0, + ( short )0x0BC8, ( short )0x0C48, ( short )0x0B30, ( short )0x0978, + ( short )0x06A8, ( short )0x0530, ( short )0x03F0, ( short )0x0438, + ( short )0x03C0, ( short )0x0350, ( short )0x0360, ( short )0x04E8, + ( short )0x0698, ( short )0x07D0, ( short )0x08D0, ( short )0x0998, + ( short )0x0A70, ( short )0x0B48, ( short )0x0B70, ( short )0x0AD0, + ( short )0x09C0, ( short )0x0890, ( short )0x0730, ( short )0x0588, + ( short )0x0358, ( short )0x0140, ( short )0xFF58, ( short )0xFD40, + ( short )0xFB68, ( short )0xF9E8, ( short )0xF828, ( short )0xF6D0, + ( short )0xF608, ( short )0xF5D8, ( short )0xF610, ( short )0xF668, + ( short )0xF778, ( short )0xF8E8, ( short )0xFA48, ( short )0xFCC8, + ( short )0xFF50, ( short )0x01C8, ( short )0x0428, ( short )0x0640, + ( short )0x07D0, ( short )0x09D0, ( short )0x0B40, ( short )0x0BF8, + ( short )0x0C30, ( short )0x0C08, ( short )0x0B08, ( short )0x0988, + ( short )0x07C0, ( short )0x0670, ( short )0x0608, ( short )0x0590, + ( short )0x0588, ( short )0x05B0, ( short )0x05E0, ( short )0x06B8, + ( short )0x0748, ( short )0x0758, ( short )0x0700, ( short )0x06A8, + ( short )0x0620, ( short )0x05D8, ( short )0x0590, ( short )0x0528, + ( short )0x03A8, ( short )0x0240, ( short )0x0108, ( short )0xFF38, + ( short )0xFD50, ( short )0xFBA0, ( short )0xFA38, ( short )0xF920, + ( short )0xF860, ( short )0xF6E8, ( short )0xF640, ( short )0xF628, + ( short )0xF680, ( short )0xF720, ( short )0xF800, ( short )0xF8E0, + ( short )0xF9A0, ( short )0xFA78, ( short )0xFB88, ( short )0xFD20, + ( short )0xFEA0, ( short )0x0008, ( short )0x0110, ( short )0x0200, + ( short )0x0360, ( short )0x04E0, ( short )0x0608, ( short )0x0738, + ( short )0x0838, ( short )0x08D8, ( short )0x0828, ( short )0x0738, + ( short )0x0600, ( short )0x04A8, ( short )0x02E0, ( short )0x0130, + ( short )0xFFA0, ( short )0xFF48, ( short )0xFF10, ( short )0xFEF0, + ( short )0xFF30, ( short )0xFFD0, ( short )0x0090, ( short )0x0090, + ( short )0x0070, ( short )0x0060, ( short )0xFFE8, ( short )0xFF50, + ( short )0xFEB8, ( short )0xFE98, ( short )0xFE88, ( short )0xFE80, + ( short )0xFE58, ( short )0xFE50, ( short )0xFE58, ( short )0xFDB0, + ( short )0xFD08, ( short )0xFC80, ( short )0xFAF8, ( short )0xF988, + ( short )0xF860, ( short )0xF798, ( short )0xF720, ( short )0xF6E8, + ( short )0xF728, ( short )0xF7C0, ( short )0xF8A8, ( short )0xF8F8, + ( short )0xF960, ( short )0xFA18, ( short )0xFAC0, ( short )0xFB58, + ( short )0xFC18, ( short )0xFCE0, ( short )0xFDA0, ( short )0xFE20, + ( short )0xFE88, ( short )0xFEF8, ( short )0xFEF0, ( short )0xFEC8, + ( short )0xFEA8, ( short )0xFDE0, ( short )0xFD10, ( short )0xFC70, + ( short )0xFBA8, ( short )0xFB10, ( short )0xFAB8, ( short )0xFAA0, + ( short )0xFAD0, ( short )0xFB18, ( short )0xFA90, ( short )0xFA18, + ( short )0xFA10, ( short )0xFA80, ( short )0xFB10, ( short )0xFB88, + ( short )0xFC90, ( short )0xFDB8, ( short )0xFEB8, ( short )0xFF80, + ( short )0x0058, ( short )0x0138, ( short )0x0118, ( short )0x00C8, + ( short )0x00C0, ( short )0xFF98, ( short )0xFE30, ( short )0xFD38, + ( short )0xFC68, ( short )0xFB78, ( short )0xFAB8, ( short )0xFAE8, + ( short )0xFB78, ( short )0xFBD0, ( short )0xFBE8, ( short )0xFC18, + ( short )0xFC98, ( short )0xFD28, ( short )0xFD48, ( short )0xFD68, + ( short )0xFD68, ( short )0xFD90, ( short )0xFDB8, ( short )0xFD90, + ( short )0xFD68, ( short )0xFD78, ( short )0xFCA0, ( short )0xFB70, + ( short )0xFAD0, ( short )0xF9F0, ( short )0xF870, ( short )0xF748, + ( short )0xF748, ( short )0xF770, ( short )0xF748, ( short )0xF720, + ( short )0xF7A8, ( short )0xF878, ( short )0xF930, ( short )0xF998, + ( short )0xFA38, ( short )0xFC10, ( short )0xFDA0, ( short )0xFE70, + ( short )0x0030, ( short )0x0248, ( short )0x03A0, ( short )0x0568, + ( short )0x0738, ( short )0x0870, ( short )0x0960, ( short )0x0A10, + ( short )0x0A40, ( short )0x0A28, ( short )0x09B8, ( short )0x08E8, + ( short )0x07E8, ( short )0x06E0, ( short )0x0588, ( short )0x0430, + ( short )0x0300, ( short )0x0260, ( short )0x01D0, ( short )0x0118, + ( short )0xFFB0, ( short )0xFE98, ( short )0xFE18, ( short )0xFDA0, + ( short )0xFD08, ( short )0xFCB8, ( short )0xFCF8, ( short )0xFD60, + ( short )0xFD90, ( short )0xFD90, ( short )0xFDD8, ( short )0xFE50, + ( short )0xFDA0, ( short )0xFCE0, ( short )0xFCC0, ( short )0xFCE8, + ( short )0xFCB0, ( short )0xFC60, ( short )0xFC70, ( short )0xFCB8, + ( short )0xFCE0, ( short )0xFD40, ( short )0xFDD8, ( short )0xFE68, + ( short )0xFF78, ( short )0x0068, ( short )0x0108, ( short )0x0278, + ( short )0x03A0, ( short )0x0420, ( short )0x0590, ( short )0x0708, + ( short )0x07B8, ( short )0x07D8, ( short )0x0808, ( short )0x0838, + ( short )0x07D8, ( short )0x06E8, ( short )0x0600, ( short )0x05B0, + ( short )0x0518, ( short )0x0410, ( short )0x02A0, ( short )0x0198, + ( short )0x00D0, ( short )0x00C8, ( short )0x00B0, ( short )0x0068, + ( short )0x00C0, ( short )0x0150, ( short )0x0180, ( short )0x0220, + ( short )0x02D8, ( short )0x0340, ( short )0x0360, ( short )0x0380, + ( short )0x0380, ( short )0x0338, ( short )0x02C8, ( short )0x02B8, + ( short )0x0280, ( short )0x0200, ( short )0x0100, ( short )0x0098, + ( short )0x0080, ( short )0x0020, ( short )0xFFF0, ( short )0x0000, + ( short )0x0020, ( short )0x0098, ( short )0x0120, ( short )0x0170, + ( short )0x0230, ( short )0x02F0, ( short )0x0350, ( short )0x0480, + ( short )0x05B8, ( short )0x0650, ( short )0x06A8, ( short )0x0738, + ( short )0x0798, ( short )0x07B0, ( short )0x07C0, ( short )0x0798, + ( short )0x0668, ( short )0x0598, ( short )0x0530, ( short )0x04C8, + ( short )0x0410, ( short )0x0350, ( short )0x0278, ( short )0x01D8, + ( short )0x0148, ( short )0x0080, ( short )0x0000, ( short )0xFFC0, + ( short )0xFFD8, ( short )0xFFA8, ( short )0xFF60, ( short )0xFF80, + ( short )0x0018, ( short )0x0070, ( short )0xFFE0, ( short )0xFF88, + ( short )0xFFC0, ( short )0xFF38, ( short )0xFE98, ( short )0xFE50, + ( short )0xFE10, ( short )0xFDD8, ( short )0xFD90, ( short )0xFD30, + ( short )0xFDB8, ( short )0xFE68, ( short )0xFE70, ( short )0xFE60, + ( short )0xFE70, ( short )0xFED0, ( short )0xFF90, ( short )0xFFE0, + ( short )0xFFF0, ( short )0x00A8, ( short )0x0168, ( short )0x01D0, + ( short )0x01F8, ( short )0x0210, ( short )0x0278, ( short )0x0268, + ( short )0x0208, ( short )0x0220, ( short )0x01F8, ( short )0x0198, + ( short )0x0158, ( short )0x0100, ( short )0x00C0, ( short )0x00A0, + ( short )0x0018, ( short )0xFF98, ( short )0xFF28, ( short )0xFEC0, + ( short )0xFE80, ( short )0xFE60, ( short )0xFD88, ( short )0xFCF0, + ( short )0xFCC8, ( short )0xFC70, ( short )0xFC10, ( short )0xFBC8, + ( short )0xFBB0, ( short )0xFBE8, ( short )0xFBE8, ( short )0xFB80, + ( short )0xFB88, ( short )0xFB40, ( short )0xFB18, ( short )0xFB20, + ( short )0xFAB8, ( short )0xFA50, ( short )0xFA50, ( short )0xFAB8, + ( short )0xFAF8, ( short )0xFB18, ( short )0xFBB0, ( short )0xFC88, + ( short )0xFD10, ( short )0xFD40, ( short )0xFD98, ( short )0xFE38, + ( short )0xFEE0, ( short )0xFEF8, ( short )0xFEF0, ( short )0xFF18, + ( short )0xFF18, ( short )0xFF18, ( short )0xFF68, ( short )0xFF98, + ( short )0xFF98, ( short )0xFFD0, ( short )0xFFF8, ( short )0x0048, + ( short )0x0038, ( short )0x0008, ( short )0x0008, ( short )0xFFE0, + ( short )0xFFB0, ( short )0xFFB8, ( short )0xFED0, ( short )0xFE18, + ( short )0xFE18, ( short )0xFDF0, ( short )0xFE38, ( short )0xFE90, + ( short )0xFE90, ( short )0xFDA8, ( short )0xFD48, ( short )0xFD70, + ( short )0xFD68, ( short )0xFD00, ( short )0xFCB8, ( short )0xFCB8, + ( short )0xFCF8, ( short )0xFD00, ( short )0xFC30, ( short )0xFBD0, + ( short )0xFC10, ( short )0xFC20, ( short )0xFBE0, ( short )0xFBA8, + ( short )0xFC30, ( short )0xFD00, ( short )0xFD50, ( short )0xFD90, + ( short )0xFE10, ( short )0xFEA8, ( short )0xFF40, ( short )0xFFA0, + ( short )0xFFD0, ( short )0xFFC8, ( short )0xFFC8, ( short )0xFFD8, + ( short )0xFFA0, ( short )0xFF98, ( short )0xFFB8, ( short )0x0050, + ( short )0x00B8, ( short )0x00B0, ( short )0x01B0, ( short )0x02E0, + ( short )0x0318, ( short )0x0330, ( short )0x02E0, ( short )0x02C8, + ( short )0x0278, ( short )0x0150, ( short )0x0050, ( short )0xFFC0, + ( short )0xFF88, ( short )0xFF18, ( short )0xFE90, ( short )0xFE40, + ( short )0xFE30, ( short )0xFDE8, ( short )0xFDD0, ( short )0xFD70, + ( short )0xFD48, ( short )0xFD10, ( short )0xFC98, ( short )0xFC38, + ( short )0xFC38, ( short )0xFC78, ( short )0xFC98, ( short )0xFCF0, + ( short )0xFDA8, ( short )0xFE48, ( short )0xFEC8, ( short )0xFF30, + ( short )0xFF98, ( short )0x0000, ( short )0x0050, ( short )0x0058, + ( short )0x00A8, ( short )0x00E8, ( short )0x00D0, ( short )0x0138, + ( short )0x01E0, ( short )0x0218, ( short )0x0208, ( short )0x0230, + ( short )0x0258, ( short )0x0248, ( short )0x02B0, ( short )0x0318, + ( short )0x0330, ( short )0x0358, ( short )0x0380, ( short )0x0378, + ( short )0x0408, ( short )0x0480, ( short )0x0460, ( short )0x03C8, + ( short )0x0318, ( short )0x02B0, ( short )0x01E8, ( short )0x00B8, + ( short )0xFFD8, ( short )0xFF30, ( short )0xFEC8, ( short )0xFE60, + ( short )0xFE60, ( short )0xFE78, ( short )0xFE78, ( short )0xFDC0, + ( short )0xFD70, ( short )0xFD50, ( short )0xFD08, ( short )0xFC88, + ( short )0xFC28, ( short )0xFC98, ( short )0xFD18, ( short )0xFD60, + ( short )0xFD60, ( short )0xFDD8, ( short )0xFE90, ( short )0xFEE8, + ( short )0xFF10, ( short )0xFF58, ( short )0xFF90, ( short )0xFFB8, + ( short )0xFFE0, ( short )0xFFF0, ( short )0xFFF0, ( short )0x00D0, + ( short )0x0190, ( short )0x01C8, ( short )0x0180, ( short )0x0188, + ( short )0x01B0, ( short )0x0238, ( short )0x0298, ( short )0x02B8, + ( short )0x0268, ( short )0x0258, ( short )0x0258, ( short )0x0230, + ( short )0x0228, ( short )0x0230, ( short )0x0258, ( short )0x0248, + ( short )0x01F8, ( short )0x0150, ( short )0x00C8, ( short )0x0058, + ( short )0x0058, ( short )0x0038, ( short )0x0000, ( short )0xFF50, + ( short )0xFF00, ( short )0xFEF8, ( short )0xFE80, ( short )0xFDB8, + ( short )0xFD70, ( short )0xFD00, ( short )0xFC90, ( short )0xFC40, + ( short )0xFC28, ( short )0xFC58, ( short )0xFC98, ( short )0xFD10, + ( short )0xFD78, ( short )0xFDE0, ( short )0xFE80, ( short )0xFF08, + ( short )0xFF60, ( short )0xFFD0, ( short )0x0030, ( short )0x0068, + ( short )0x0110, ( short )0x0198, ( short )0x01C0, ( short )0x0208, + ( short )0x0260, ( short )0x0280, ( short )0x0320, ( short )0x0390, + ( short )0x0398, ( short )0x0410, ( short )0x0488, ( short )0x04A0, + ( short )0x0448, ( short )0x0408, ( short )0x03E0, ( short )0x03C8, + ( short )0x0398, ( short )0x0350, ( short )0x0308, ( short )0x02C8, + ( short )0x0278, ( short )0x01D8, ( short )0x0148, ( short )0x00E8, + ( short )0x0040, ( short )0xFFA0, ( short )0xFF50, ( short )0xFDC0, + ( short )0xFC88, ( short )0xFC30, ( short )0xFB88, ( short )0xFAA8, + ( short )0xFA50, ( short )0xFA30, ( short )0xFA40, ( short )0xFA70, + ( short )0xFAB8, ( short )0xFAE0, ( short )0xFB28, ( short )0xFB58, + ( short )0xFB80, ( short )0xFBB0, ( short )0xFC00, ( short )0xFC80, + ( short )0xFCF0, ( short )0xFDB8, ( short )0xFE58, ( short )0xFED8, + ( short )0x0008, ( short )0x0100, ( short )0x0180, ( short )0x01D0, + ( short )0x0210, ( short )0x0248, ( short )0x0238, ( short )0x0200, + ( short )0x01D0, ( short )0x02D0, ( short )0x03A0, ( short )0x03D8, + ( short )0x03C0, ( short )0x03D8, ( short )0x03F8, ( short )0x0370, + ( short )0x02C0, ( short )0x0258, ( short )0x01B8, ( short )0x0120, + ( short )0x0090, ( short )0x0088, ( short )0x00A8, ( short )0x00A8, + ( short )0x0088, ( short )0x0068, ( short )0x0060, ( short )0xFFE0, + ( short )0xFF00, ( short )0xFE50, ( short )0xFDC8, ( short )0xFCF0, + ( short )0xFC30, ( short )0xFBB0, ( short )0xFBD8, ( short )0xFC20, + ( short )0xFC58, ( short )0xFC30, ( short )0xFC40, ( short )0xFC78, + ( short )0xFCC0, ( short )0xFCE8, ( short )0xFD10, ( short )0xFD48, + ( short )0xFD88, ( short )0xFDE8, ( short )0xFF10, ( short )0x0020, + ( short )0x0110, ( short )0x01B8, ( short )0x0248, ( short )0x02C0, + ( short )0x0358, ( short )0x03B8, ( short )0x03C8, ( short )0x0320, + ( short )0x0288, ( short )0x0280, ( short )0x0300, ( short )0x0340, + ( short )0x0320, ( short )0x0380, ( short )0x03F8, ( short )0x0418, + ( short )0x0378, ( short )0x02E0, ( short )0x0288, ( short )0x0280, + ( short )0x0238, ( short )0x01D0, ( short )0x0168, ( short )0x0138, + ( short )0x0110, ( short )0x0140, ( short )0x0148, ( short )0x0150, + ( short )0x00A8, ( short )0x0010, ( short )0xFFB0, ( short )0xFEB8, + ( short )0xFDE0, ( short )0xFD48, ( short )0xFCE8, ( short )0xFCA8, + ( short )0xFC78, ( short )0xFC48, ( short )0xFC50, ( short )0xFC70, + ( short )0xFCA8, ( short )0xFCE8, ( short )0xFD28, ( short )0xFDD0, + ( short )0xFE70, ( short )0xFED8, ( short )0x0040, ( short )0x0188, + ( short )0x0258, ( short )0x03C0, ( short )0x04F0, ( short )0x05B8, + ( short )0x0638, ( short )0x0670, ( short )0x0690, ( short )0x0708, + ( short )0x0708, ( short )0x06B8, ( short )0x0660, ( short )0x0650, + ( short )0x0630, ( short )0x05C8, ( short )0x0578, ( short )0x0548, + ( short )0x0508, ( short )0x0470, ( short )0x03D0, ( short )0x0350, + ( short )0x0278, ( short )0x01A0, ( short )0x00F8, ( short )0x00B0, + ( short )0x0078, ( short )0x0030, ( short )0xFFE8, ( short )0xFFC8, + ( short )0xFFB8, ( short )0xFED0, ( short )0xFE08, ( short )0xFD98, + ( short )0xFC70, ( short )0xFB60, ( short )0xFAA8, ( short )0xFA10, + ( short )0xF9B8, ( short )0xF980, ( short )0xF9A0, ( short )0xFA00, + ( short )0xFA68, ( short )0xFB90, ( short )0xFCB8, ( short )0xFD98, + ( short )0xFE68, ( short )0xFF18, ( short )0xFFC0, ( short )0x0078, + ( short )0x00F8, ( short )0x0218, ( short )0x0320, ( short )0x03C0, + ( short )0x0478, ( short )0x0510, ( short )0x0570, ( short )0x05D8, + ( short )0x05E0, ( short )0x05B8, ( short )0x0508, ( short )0x0468, + ( short )0x03E0, ( short )0x02F0, ( short )0x0218, ( short )0x0168, + ( short )0x00F0, ( short )0x0060, ( short )0xFFD0, ( short )0xFF58, + ( short )0xFEC0, ( short )0xFE48, ( short )0xFDB0, ( short )0xFD58, + ( short )0xFD38, ( short )0xFCD8, ( short )0xFC80, ( short )0xFC50, + ( short )0xFC08, ( short )0xFB48, ( short )0xFA98, ( short )0xF9F8, + ( short )0xF8F8, ( short )0xF810, ( short )0xF7F8, ( short )0xF818, + ( short )0xF848, ( short )0xF8E8, ( short )0xF9E0, ( short )0xFB08, + ( short )0xFC38, ( short )0xFD10, ( short )0xFDE8, ( short )0xFF10, + ( short )0xFFD0, ( short )0x0048, ( short )0x00E0, ( short )0x0160, + ( short )0x01B8, ( short )0x01C8, ( short )0x01E0, ( short )0x0200, + ( short )0x0228, ( short )0x0240, ( short )0x0240, ( short )0x0240, + ( short )0x0260, ( short )0x0280, ( short )0x0280, ( short )0x02F0, + ( short )0x0370, ( short )0x03C8, ( short )0x03C8, ( short )0x03A8, + ( short )0x03A0, ( short )0x02F8, ( short )0x0220, ( short )0x0150, + ( short )0x0098, ( short )0xFFE0, ( short )0xFF20, ( short )0xFEA0, + ( short )0xFE50, ( short )0xFE18, ( short )0xFD38, ( short )0xFC60, + ( short )0xFBE0, ( short )0xFAC8, ( short )0xF9A0, ( short )0xF8B8, + ( short )0xF830, ( short )0xF888, ( short )0xF8B8, ( short )0xF908, + ( short )0xFA80, ( short )0xFBF8, ( short )0xFD48, ( short )0xFEC8, + ( short )0x0040, ( short )0x01B0, ( short )0x0298, ( short )0x0338, + ( short )0x03C0, ( short )0x0470, ( short )0x0520, ( short )0x0588, + ( short )0x0610, ( short )0x0688, ( short )0x06C8, ( short )0x0670, + ( short )0x05E8, ( short )0x0578, ( short )0x0580, ( short )0x0578, + ( short )0x0528, ( short )0x0498, ( short )0x0408, ( short )0x0390, + ( short )0x03F8, ( short )0x0458, ( short )0x0488, ( short )0x0468, + ( short )0x0450, ( short )0x0458, ( short )0x03A8, ( short )0x02D0, + ( short )0x0210, ( short )0x0158, ( short )0x0088, ( short )0xFFA8, + ( short )0xFF00, ( short )0xFE88, ( short )0xFE30, ( short )0xFD88, + ( short )0xFCB8, ( short )0xFC28, ( short )0xFB30, ( short )0xF9F0, + ( short )0xF8E8, ( short )0xF890, ( short )0xF890, ( short )0xF8C0, + ( short )0xF978, ( short )0xFA78, ( short )0xFBE8, ( short )0xFD20, + ( short )0xFE28, ( short )0xFF60, ( short )0x00D8, ( short )0x0220, + ( short )0x02F8, ( short )0x0378, ( short )0x03E0, ( short )0x0438, + ( short )0x0488, ( short )0x0498, ( short )0x04A8, ( short )0x0480, + ( short )0x0440, ( short )0x03C0, ( short )0x02D8, ( short )0x01E8, + ( short )0x0140, ( short )0x00D8, ( short )0x0068, ( short )0xFFE0, + ( short )0x0068, ( short )0x0130, ( short )0x0228, ( short )0x0260, + ( short )0x0278, ( short )0x02D0, ( short )0x02D8, ( short )0x0290, + ( short )0x01E0, ( short )0x00D0, ( short )0xFFE0, ( short )0xFEF8, + ( short )0xFE08, ( short )0xFD28, ( short )0xFC88, ( short )0xFBE0, + ( short )0xFB60, ( short )0xFAD8, ( short )0xFA08, ( short )0xF978, + ( short )0xF8E8, ( short )0xF8B0, ( short )0xF8B0, ( short )0xF8D0, + ( short )0xF9D0, ( short )0xFAF8, ( short )0xFC18, ( short )0xFDB0, + ( short )0xFF38, ( short )0x00A0, ( short )0x01F8, ( short )0x02F8, + ( short )0x03C0, ( short )0x0460, ( short )0x04B8, ( short )0x04C8, + ( short )0x04C8, ( short )0x04C0, ( short )0x0498, ( short )0x0490, + ( short )0x0478, ( short )0x0448, ( short )0x0420, ( short )0x03F8, + ( short )0x0328, ( short )0x0238, ( short )0x01B0, ( short )0x0170, + ( short )0x0128, ( short )0x0090, ( short )0x00E8, ( short )0x01B8, + ( short )0x02B8, ( short )0x0280, ( short )0x0218, ( short )0x0218, + ( short )0x01F0, ( short )0x0148, ( short )0x0000, ( short )0xFEC0, + ( short )0xFE08, ( short )0xFD70, ( short )0xFCA0, ( short )0xFBF0, + ( short )0xFBC0, ( short )0xFBA0, ( short )0xFB80, ( short )0xFB18, + ( short )0xFB28, ( short )0xFB98, ( short )0xFBC0, ( short )0xFBD0, + ( short )0xFC08, ( short )0xFC78, ( short )0xFDC8, ( short )0xFEC8, + ( short )0xFF78, ( short )0x00D0, ( short )0x0238, ( short )0x0360, + ( short )0x0398, ( short )0x0360, ( short )0x0368, ( short )0x0380, + ( short )0x0318, ( short )0x0250, ( short )0x0208, ( short )0x0220, + ( short )0x0218, ( short )0x01F0, ( short )0x01C8, ( short )0x0210, + ( short )0x0270, ( short )0x0270, ( short )0x0240, ( short )0x0290, + ( short )0x0310, ( short )0x0360, ( short )0x0340, ( short )0x0310, + ( short )0x0318, ( short )0x0320, ( short )0x02D8, ( short )0x0240, + ( short )0x0158, ( short )0x00A0, ( short )0x0008, ( short )0xFF30, + ( short )0xFE50, ( short )0xFDA8, ( short )0xFD28, ( short )0xFCC8, + ( short )0xFC60, ( short )0xFBA8, ( short )0xFB40, ( short )0xFB10, + ( short )0xFB18, ( short )0xFB28, ( short )0xFB48, ( short )0xFB68, + ( short )0xFBA8, ( short )0xFBF8, ( short )0xFCB8, ( short )0xFD78, + ( short )0xFE00, ( short )0xFE88, ( short )0xFF30, ( short )0xFF98, + ( short )0xFFC8, ( short )0xFFE8, ( short )0x0050, ( short )0x00B0, + ( short )0x00E0, ( short )0x0040, ( short )0xFF68, ( short )0xFED8, + ( short )0xFEE8, ( short )0xFEE0, ( short )0xFE90, ( short )0xFEA8, + ( short )0xFF88, ( short )0x0080, ( short )0x0188, ( short )0x0208, + ( short )0x0290, ( short )0x0390, ( short )0x0438, ( short )0x0450, + ( short )0x0428, ( short )0x03F8, ( short )0x03E0, ( short )0x0388, + ( short )0x02E0, ( short )0x0240, ( short )0x0190, ( short )0x00D0, + ( short )0x0000, ( short )0x0000, ( short )0x0018, ( short )0x00FF, + ( short )0x0068, ( short )0x00FE, ( short )0x00F8, ( short )0x00FD +}; + +gsm_byte gsm_dec_gsmdata[] = { + 0xD5, 0x1F, 0x74, 0x21, 0xA0, 0x50, 0x40, 0xC9, 0x24, 0x7B, 0xFA, 0x6B, + 0x52, 0xE0, 0xB6, 0xD6, 0x8E, 0xB9, 0x2B, 0xAE, 0xE0, 0x8B, 0x23, 0x52, + 0x3B, 0x13, 0x86, 0xE0, 0x14, 0x4A, 0x41, 0x44, 0x32, 0xD3, 0xA1, 0x83, + 0xA1, 0x1D, 0xA6, 0x80, 0xBA, 0xD2, 0x96, 0x26, 0xFB, 0x84, 0x80, 0x6D, + 0x9C, 0x25, 0x1D, 0x9B, 0xAA, 0xC0, 0xBB, 0x4C, 0x95, 0xB9, 0x53, 0xAE, + 0xA0, 0xB6, 0xE4, 0x46, 0x37, 0x1B, 0xD4, 0xA5, 0x7B, 0x1D, 0x22, 0x97, + 0x00, 0xBA, 0xA5, 0x6D, 0xD2, 0xA1, 0x7E, 0xC0, 0xB9, 0x25, 0xD2, 0xB4, + 0x94, 0x9E, 0xE0, 0x3E, 0xDE, 0xED, 0xD6, 0xD2, 0xE2, 0xC0, 0xD7, 0x5D, + 0x8D, 0x59, 0xAC, 0xD3, 0xE4, 0x83, 0x95, 0x59, 0xC0, 0xA1, 0x48, 0xD2, + 0x66, 0xC7, 0x2C, 0x9E, 0xA0, 0x2A, 0xD3, 0xEE, 0x45, 0x1C, 0x80, 0xE0, + 0x6B, 0x34, 0x8C, 0x4B, 0x29, 0xCB, 0x00, 0xBA, 0xF6, 0x0D, 0x26, 0x9A, + 0xD3, 0xA4, 0x82, 0x9D, 0x63, 0x7A, 0xC0, 0x67, 0x24, 0xBA, 0xD6, 0x7C, + 0xC2, 0xC0, 0x37, 0x20, 0x4F, 0x10, 0xE0, 0xC7, 0x80, 0x6A, 0x77, 0x63, + 0xBE, 0x6B, 0x5A, 0xC0, 0xB5, 0x34, 0xD1, 0x34, 0x9C, 0xD4, 0xE8, 0x56, + 0xB2, 0x58, 0x5F, 0x00, 0xB7, 0xAF, 0x92, 0x12, 0x90, 0xD5, 0xA4, 0x39, + 0x23, 0x4E, 0x46, 0x87, 0x51, 0xAC, 0xD8, 0xDB, 0x6D, 0xCB, 0x17, 0x50, + 0x89, 0x7B, 0x44, 0x28, 0x03, 0x6B, 0xD5, 0xA9, 0x36, 0x36, 0xD9, 0x6B, + 0xA8, 0x93, 0x3A, 0x96, 0xEE, 0xFF, 0x67, 0x8B, 0x36, 0xDA, 0x09, 0xB4, + 0x99, 0x67, 0x2B, 0x88, 0xE4, 0xB5, 0xA5, 0xDA, 0x65, 0x47, 0xDA, 0x1E, + 0x96, 0xFA, 0xEC, 0xD5, 0xA9, 0x45, 0x63, 0x1A, 0xCB, 0xC9, 0x48, 0x9D, + 0x83, 0x5F, 0x6F, 0xCB, 0x08, 0x1B, 0x97, 0xC9, 0x18, 0x0A, 0x63, 0xCB, + 0xA6, 0xE1, 0x84, 0xF5, 0x62, 0x61, 0x6A, 0x84, 0xDC, 0xB6, 0x37, 0x9E, + 0xD6, 0xAB, 0x3C, 0x53, 0x93, 0xC1, 0x2A, 0xAA, 0x81, 0x8D, 0x6B, 0x65, + 0x60, 0xA8, 0xFB, 0x2E, 0x22, 0x59, 0x74, 0x61, 0xA6, 0x5D, 0x73, 0x94, + 0xF8, 0xE4, 0xC1, 0x46, 0x26, 0x5E, 0x8A, 0x86, 0xED, 0xD4, 0xA6, 0x2D, + 0x57, 0x6B, 0xBE, 0xE8, 0x58, 0xDA, 0x3D, 0x98, 0x99, 0xBE, 0xA8, 0xC2, + 0xDB, 0x6A, 0x2E, 0x51, 0x62, 0xE5, 0x80, 0x58, 0x76, 0xB8, 0xE4, 0x6C, + 0x84, 0xCA, 0x98, 0x06, 0x0B, 0xFC, 0xD2, 0x66, 0x7C, 0x62, 0x3A, 0x5B, + 0xC5, 0xDF, 0x7D, 0x75, 0x49, 0x1E, 0x52, 0xC7, 0x55, 0xF7, 0x84, 0xA6, + 0xDA, 0x5D, 0x43, 0x26, 0x85, 0x98, 0xD8, 0x8F, 0xB6, 0xC5, 0x28, 0xEB, + 0x3E, 0x75, 0x04, 0xD2, 0x27, 0xBA, 0x2A, 0x2B, 0xB7, 0x03, 0x13, 0x45, + 0x35, 0x1B, 0x78, 0x5F, 0xC3, 0xBA, 0xDB, 0xAE, 0x27, 0xC2, 0x5E, 0xA4, + 0x50, 0x8C, 0x8A, 0xBB, 0x4F, 0x60, 0xC3, 0xEE, 0x41, 0x46, 0x4A, 0xDF, + 0xD2, 0x27, 0xB2, 0xAD, 0xEB, 0x5F, 0x43, 0x4C, 0x6A, 0x09, 0x2A, 0xCC, + 0xB7, 0x47, 0x2A, 0xB9, 0x91, 0xB6, 0xD4, 0x5B, 0x25, 0x58, 0xD8, 0xFD, + 0x46, 0x95, 0x5A, 0xC3, 0x27, 0x5B, 0x3F, 0xFB, 0x12, 0xD2, 0x26, 0xC3, + 0xA9, 0xA1, 0xB6, 0xA2, 0xCB, 0x1B, 0xD0, 0x73, 0xE4, 0xBA, 0xA1, 0xE9, + 0x05, 0xBE, 0x79, 0x23, 0xA4, 0xC2, 0x3A, 0x4B, 0x11, 0xE5, 0x68, 0xC4, + 0xC1, 0xBA, 0xC1, 0xCC, 0x8B, 0x02, 0xD2, 0x63, 0x6C, 0xEE, 0x19, 0x5E, + 0xE1, 0xB6, 0x4C, 0x1A, 0xB4, 0x5E, 0xF0, 0xC2, 0x27, 0x20, 0x55, 0xBD, + 0x6D, 0x64, 0xE1, 0xC7, 0x45, 0xA9, 0x65, 0x6D, 0x7D, 0x42, 0x56, 0xD8, + 0xB2, 0xB6, 0xEC, 0xD3, 0x61, 0x5B, 0x62, 0x61, 0x60, 0xA1, 0x5B, 0xD6, + 0x15, 0x29, 0x09, 0x6C, 0xA1, 0x3E, 0xAD, 0x65, 0x34, 0xC3, 0xC0, 0xC1, + 0x22, 0x6D, 0x4C, 0x57, 0x10, 0xDB, 0x41, 0xD2, 0xE1, 0x77, 0x64, 0xF7, + 0xD3, 0x21, 0x73, 0xA9, 0x29, 0x58, 0xC1, 0xA1, 0x5A, 0x52, 0xB7, 0x32, + 0x64, 0xC1, 0x67, 0x42, 0x74, 0x2C, 0xDC, 0x61, 0x61, 0x65, 0x8B, 0xCB, + 0x04, 0xE5, 0x60, 0xC1, 0xC9, 0x5E, 0x8E, 0x36, 0x83, 0xD2, 0xA2, 0x83, + 0xA9, 0xD9, 0xCD, 0x21, 0xB9, 0x25, 0xCD, 0xE6, 0x1D, 0x60, 0xA1, 0xB4, + 0xAA, 0x8F, 0xBA, 0x75, 0xC3, 0x01, 0x0B, 0x3B, 0x51, 0xDB, 0xEC, 0x62, + 0xE1, 0x38, 0xCD, 0x40, 0x3B, 0xD3, 0xD2, 0x26, 0x94, 0x29, 0xD2, 0x61, + 0x21, 0x6B, 0x4A, 0x8D, 0x24, 0xB5, 0xBB, 0x21, 0x12, 0xA5, 0x99, 0xA5, + 0x1A, 0xCA, 0xA1, 0xEF, 0x5D, 0xAA, 0xAE, 0xD3, 0x64, 0xE1, 0xA3, 0x6B, + 0xAE, 0x35, 0x39, 0xD2, 0x66, 0x73, 0xB6, 0x90, 0xC6, 0xC1, 0x32, 0xD1, + 0xBA, 0xC9, 0x25, 0x65, 0x81, 0xA8, 0xD2, 0xB1, 0xE7, 0x18, 0xBE, 0xC0, + 0xFC, 0xE4, 0x85, 0xB5, 0x06, 0xB4, 0x81, 0x35, 0x46, 0xB6, 0xC8, 0x9B +}; + +#endif /* GSM_DEC_DATA_H */ diff --git a/all_pairs/source/gsm_dec/gsm.h b/all_pairs/source/gsm_dec/gsm.h new file mode 100644 index 0000000..1d89577 --- /dev/null +++ b/all_pairs/source/gsm_dec/gsm.h @@ -0,0 +1,14 @@ +#ifndef GSM_DEC_GSM_H +#define GSM_DEC_GSM_H + +/* + Interface +*/ +typedef struct gsm_state *gsm; +typedef short gsm_signal; /* signed 16 bit */ +typedef unsigned char gsm_byte; +typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ + +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +#endif /* GSM_DEC_GSM_H */ diff --git a/all_pairs/source/gsm_dec/gsm_dec.c b/all_pairs/source/gsm_dec/gsm_dec.c new file mode 100644 index 0000000..7a0a1bd --- /dev/null +++ b/all_pairs/source/gsm_dec/gsm_dec.c @@ -0,0 +1,764 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: gsm_dec + + Author: Jutta Degener and Carsten Bormann, + Technische Universitaet Berlin + + Function: Decoding of GSM data + + Source: included in MediaBench/gsm + + Original name: gsm_decode + + Changes: no major functional changes + + License: see the accompanying COPYRIGHT file + +*/ + + +#include "../extra.h" +#include "gsm.h" +#include "add.h" +#include "data.h" +#include "private.h" + +#define SAMPLES 20 + +/* + Forward declaration of global variables +*/ + +struct gsm_state gsm_dec_state; +gsm gsm_dec_state_ptr; +volatile int gsm_dec_result; + +/* + Forward declaration of functions +*/ + +extern word gsm_dec_sub( word a, word b ); +extern word gsm_dec_asl( word a, int n ); +void gsm_dec_Decoding_of_the_coded_Log_Area_Ratios( + word *LARc, /* coded log area ratio [0..7] IN */ + word *LARpp ); /* out: decoded .. */ + +void gsm_dec_Coefficients_0_12( word *LARpp_j_1, word *LARpp_j, word *LARp ); + +void gsm_dec_LARp_to_rp( word *LARp ); /* [0..7] IN/OUT */ + +extern int gsm_dec_decode( gsm, gsm_byte *, gsm_signal * ); + +extern void gsm_dec_Decoder( struct gsm_state *S, + word *LARcr, /* [0..7] IN */ + word *Ncr, /* [0..3] IN */ + word *bcr, /* [0..3] IN */ + word *Mcr, /* [0..3] IN */ + word *xmaxcr, /* [0..3] IN */ + word *xMcr, /* [0..13*4] IN */ + word *s ); /* [0..159] OUT */ + +extern void gsm_dec_Long_Term_Synthesis_Filtering( + struct gsm_state *S, word Ncr, word bcr, + word *erp, /* [0..39] IN */ + word *drp ); /* [-120..-1] IN, [0..40] OUT */ + +void gsm_dec_RPE_Decoding( word xmaxcr, word Mcr, + word *xMcr, /* [0..12], 3 bits IN */ + word *erp ); /* [0..39] OUT */ + +void gsm_dec_RPE_grid_positioning( word Mc, /* grid position IN */ + word *xMp, /* [0..12] IN */ + word *ep /* [0..39] OUT */ + ); + +void gsm_dec_APCM_inverse_quantization( word *xMc, /* [0..12] IN */ + word mant, word exp, + word *xMp ); /* [0..12] OUT */ + +extern word gsm_dec_asr( word a, int n ); + +void gsm_dec_APCM_quantization_xmaxc_to_exp_mant( + word xmaxc, /* IN */ + word *exp_out, /* OUT */ + word *mant_out ); /* OUT */ + +void gsm_dec_Postprocessing( struct gsm_state *S, word *s ); + +void gsm_dec_Coefficients_13_26( word *LARpp_j_1, word *LARpp_j, + word *LARp ); + +void gsm_dec_Coefficients_40_159( word *LARpp_j, word *LARp ); + +void gsm_dec_Short_term_synthesis_filtering( struct gsm_state *S, + word *rrp, /* [0..7] IN */ + int k, /* k_end - k_start */ + word *wt, /* [0..k-1] IN */ + word *sr /* [0..k-1] OUT */ + ); + +void gsm_dec_Short_Term_Synthesis_Filter( + struct gsm_state *S, word *LARcr, /* received log area ratios [0..7] IN */ + word *wt, /* received d [0..159] IN */ + word *s /* signal s [0..159] OUT */ +); + +void gsm_dec_Coefficients_27_39( word *LARpp_j_1, word *LARpp_j, word *LARp ); + +gsm gsm_dec_create( void ); +void gsm_dec_init( void ); +void gsm_dec_main( void ); +//int main( void ); + +/* add.c */ + +word gsm_dec_sub( word a, word b ) +{ + longword diff = ( longword )a - ( longword )b; + return saturate( diff ); +} + +word gsm_dec_asl( word a, int n ) +{ + if ( n >= 16 ) + return 0; + if ( n <= -16 ) + return -( a < 0 ); + if ( n < 0 ) + return gsm_dec_asr( a, -n ); + return a << n; +} + +/* short_term.c */ +/* + SHORT TERM ANALYSIS FILTERING SECTION +*/ + +/* 4.2.8 */ + +void gsm_dec_Decoding_of_the_coded_Log_Area_Ratios( + word *LARc, /* coded log area ratio [0..7] IN */ + word *LARpp ) /* out: decoded .. */ +{ + word temp1 /* for STEP */; + long ltmp; /* for GSM_ADD */ + + /* This procedure requires for efficient implementation + two tables. + + INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) + MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] + */ + + /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { + + temp1 = GSM_ADD( *LARc, *MIC ) << 10; + temp2 = *B << 1; + temp1 = GSM_SUB( temp1, temp2 ); + + temp1 = GSM_MULT_R( *INVA, temp1 ); + LARpp = GSM_ADD( temp1, temp1 ); + } + */ + +#undef STEP +#define STEP(B, MIC, INVA) \ + temp1 = GSM_ADD(*LARc++, MIC) << 10; \ + temp1 = GSM_SUB(temp1, B << 1); \ + temp1 = GSM_MULT_R(INVA, temp1); \ + *LARpp++ = GSM_ADD(temp1, temp1); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( 2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( 1792, -8, 17476 ); + STEP( 341, -4, 31454 ); + STEP( 1144, -4, 29708 ); + + /* NOTE: the addition of *MIC is used to restore the sign of *LARc. + */ +} + +/* 4.2.9 */ +/* Computation of the quantized reflection coefficients +*/ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] +*/ + +/* + Within each frame of 160 analyzed speech samples the short term + analysis and synthesis filters operate with four different sets of + coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) + and the actual set of decoded LARs (LARpp(j)) + + (Initial value: LARpp(j-1)[1..8] = 0.) +*/ + + +void gsm_dec_Coefficients_0_12( word *LARpp_j_1, word *LARpp_j, word *LARp ) +{ + int i; + longword ltmp; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++ ) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ) ); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1 ) ); + } +} + +/* 4.2.9.2 */ + +void gsm_dec_LARp_to_rp( word *LARp ) /* [0..7] IN/OUT */ +/* + The input of this procedure is the interpolated LARp[0..7] array. + The reflection coefficients, rp[i], are used in the analysis + filter and in the synthesis filter. +*/ +{ + int i; + word temp; + longword ltmp; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARp++ ) { + + /* temp = GSM_ABS( *LARp ); + + if (temp < 11059) temp <<= 1; + else if (temp < 20070) temp += 11059; + else temp = GSM_ADD( temp >> 2, 26112 ); + + * *LARp = *LARp < 0 ? -temp : temp; + */ + + if ( *LARp < 0 ) { + temp = *LARp == MIN_WORD ? MAX_WORD : -( *LARp ); + *LARp = -( ( temp < 11059 ) ? temp << 1 + : ( ( temp < 20070 ) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 ) ) ); + } else { + temp = *LARp; + *LARp = ( temp < 11059 ) + ? temp << 1 + : ( ( temp < 20070 ) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 ) ); + } + } +} + +void gsm_dec_Decoder( struct gsm_state *S, + word *LARcr, /* [0..7] IN */ + word *Ncr, /* [0..3] IN */ + word *bcr, /* [0..3] IN */ + word *Mcr, /* [0..3] IN */ + word *xmaxcr, /* [0..3] IN */ + word *xMcr, /* [0..13*4] IN */ + word *s ) /* [0..159] OUT */ +{ + int j, k; + word erp[40], wt[160]; + word *drp = S->dp0 + 120; + + _Pragma( "loopbound min 4 max 4" ) + for ( j = 0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13 ) { + + gsm_dec_RPE_Decoding( *xmaxcr, *Mcr, xMcr, erp ); + gsm_dec_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); + + _Pragma( "loopbound min 40 max 40" ) + for ( k = 0; k <= 39; k++ ) + wt[j * 40 + k] = drp[k]; + } + + gsm_dec_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); + gsm_dec_Postprocessing( S, s ); +} + +/* 4.3.2 */ +void gsm_dec_Long_Term_Synthesis_Filtering( + struct gsm_state *S, + word Ncr, word bcr, word *erp, /* [0..39] IN */ + word *drp /* [-120..-1] IN, [0..40] OUT */ +) +/* + This procedure uses the bcr and Ncr parameter to realize the + long term synthesis filtering. The decoding of bcr needs + table 4.3b. +*/ +{ + longword ltmp; /* for ADD */ + int k; + word brp, drpp, Nr; + + /* Check the limits of Nr. + */ + Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; + S->nrp = Nr; + + /* Decoding of the LTP gain bcr + */ + brp = gsm_dec_QLB[bcr]; + + /* Computation of the reconstructed short term residual + signal drp[0..39] + */ + + _Pragma( "loopbound min 40 max 40" ) + for ( k = 0; k <= 39; k++ ) { + drpp = GSM_MULT_R( brp, drp[k - Nr] ); + drp[k] = GSM_ADD( erp[k], drpp ); + } + + /* + Update of the reconstructed short term residual signal + drp[ -1..-120 ] + */ + + _Pragma( "loopbound min 120 max 120" ) + for ( k = 0; k <= 119; k++ ) + drp[-120 + k] = drp[-80 + k]; +} + +void gsm_dec_RPE_Decoding( word xmaxcr, word Mcr, + word *xMcr, /* [0..12], 3 bits IN */ + word *erp ) /* [0..39] OUT */ +{ + word exp, mant; + word xMp[13]; + + gsm_dec_APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); + gsm_dec_APCM_inverse_quantization( xMcr, mant, exp, xMp ); + gsm_dec_RPE_grid_positioning( Mcr, xMp, erp ); +} + +/* 4.2.17 */ +void gsm_dec_RPE_grid_positioning( + word Mc, /* grid position IN */ + word *xMp, /* [0..12] IN */ + word *ep /* [0..39] OUT */ ) +/* + This procedure computes the reconstructed long term residual signal + ep[0..39] for the LTP analysis filter. The inputs are the Mc + which is the grid position selection and the xMp[0..12] decoded + RPE samples which are upsampled by a factor of 3 by inserting zero + values. +*/ +{ + int i = 13; + + /* Rewritten Duff's device for WCET analysis! */ + switch ( Mc ) { + case 3: + *ep++ = 0; + case 2: + *ep++ = 0; + case 1: + *ep++ = 0; + case 0: + *ep++ = *xMp++; + i--; + } + + _Pragma( "loopbound min 12 max 12" ) + do { + *ep++ = 0; + *ep++ = 0; + *ep++ = *xMp++; + } while ( --i ); + + _Pragma( "loopbound min 0 max 2" ) + while ( ++Mc < 4 ) + *ep++ = 0; + +} + +/* 4.2.16 */ +void gsm_dec_APCM_inverse_quantization( word *xMc, /* [0..12] IN */ + word mant, + word exp, + word *xMp ) /* [0..12] OUT */ +/* + This part is for decoding the RPE sequence of coded xMc[0..12] + samples to obtain the xMp[0..12] array. Table 4.6 is used to get + the mantissa of xmaxc (FAC[0..7]). +*/ +{ + int i; + word temp, temp1, temp2, temp3; + longword ltmp; + + temp1 = gsm_dec_FAC[mant]; /* see 4.2-15 for mant */ + temp2 = gsm_dec_sub( 6, exp ); /* see 4.2-15 for exp */ + temp3 = gsm_dec_asl( 1, gsm_dec_sub( temp2, 1 ) ); + + _Pragma( "loopbound min 13 max 13" ) + for ( i = 13; i--; ) { + + /* temp = gsm_sub( *xMc++ << 1, 7 ); */ + temp = ( *xMc++ << 1 ) - 7; /* restore sign */ + + temp <<= 12; /* 16 bit signed */ + temp = GSM_MULT_R( temp1, temp ); + temp = GSM_ADD( temp, temp3 ); + *xMp++ = gsm_dec_asr( temp, temp2 ); + } +} + +/* + 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION +*/ +word gsm_dec_asr( word a, int n ) +{ + if ( n >= 16 ) + return -( a < 0 ); + if ( n <= -16 ) + return 0; + if ( n < 0 ) + return a << -n; + + return a >> n; +} + +/* rpe.c */ +/* 4.12.15 */ +void gsm_dec_APCM_quantization_xmaxc_to_exp_mant( word xmaxc, /* IN */ + word *exp_out, /* OUT */ + word *mant_out ) /* OUT */ +{ + word exp, mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + exp = 0; + if ( xmaxc > 15 ) + exp = SASR( xmaxc, 3 ) - 1; + mant = xmaxc - ( exp << 3 ); + + if ( mant == 0 ) { + exp = -4; + mant = 7; + } else { + _Pragma( "loopbound min 0 max 3" ) + while ( mant <= 7 ) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; +} + +/* decode.c */ +/* + 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER +*/ +void gsm_dec_Postprocessing( struct gsm_state *S, word *s ) +{ + int k; + word msr = S->msr; + longword ltmp; /* for GSM_ADD */ + word tmp; + + _Pragma( "loopbound min 159 max 159" ) + for ( k = 160; --k; ++s ) { + tmp = GSM_MULT_R( msr, 28180 ); + msr = GSM_ADD( *s, tmp ); /* Deemphasis */ + *s = GSM_ADD( msr, msr ) & 0xFFF8; /* Truncation & Upscaling */ + } + S->msr = msr; +} + +void gsm_dec_Coefficients_13_26( word *LARpp_j_1, word *LARpp_j, word *LARp ) +{ + int i; + longword ltmp; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++ ) + *LARp = GSM_ADD( SASR( *LARpp_j_1, 1 ), SASR( *LARpp_j, 1 ) ); +} + +void gsm_dec_Coefficients_40_159( word *LARpp_j, word *LARp ) +{ + int i; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARp++, LARpp_j++ ) + *LARp = *LARpp_j; +} + +void gsm_dec_Short_term_synthesis_filtering( struct gsm_state *S, + word *rrp, /* [0..7] IN */ + int k, /* k_end - k_start */ + word *wt, /* [0..k-1] IN */ + word *sr ) /* [0..k-1] OUT */ +{ + word *v = S->v; + int i; + word sri, tmp1, tmp2; + longword ltmp; /* for GSM_ADD & GSM_SUB */ + + _Pragma( "loopbound min 12 max 118" ) + while ( --k ) { + sri = *wt++; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 8; i--; ) { + + /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); + */ + tmp1 = rrp[i]; + tmp2 = v[i]; + tmp2 = + ( tmp1 == MIN_WORD && tmp2 == MIN_WORD + ? MAX_WORD + : 0x0FFFF & ( ( ( longword )tmp1 * ( longword )tmp2 + 16384 ) >> 15 ) ); + + sri = GSM_SUB( sri, tmp2 ); + + /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); + */ + tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD + ? MAX_WORD + : 0x0FFFF & ( ( ( longword )tmp1 * ( longword )sri + 16384 ) >> 15 ) ); + + v[i + 1] = GSM_ADD( v[i], tmp1 ); + } + *sr++ = v[0] = sri; + } +} + +void gsm_dec_Short_Term_Synthesis_Filter( + struct gsm_state *S, + word *LARcr, /* received log area ratios [0..7] IN */ + word *wt, /* received d [0..159] IN */ + word *s /* signal s [0..159] OUT */ +) +{ + word *LARpp_j = S->LARpp[S->j]; + word *LARpp_j_1 = S->LARpp[S->j ^= 1]; + + word LARp[8]; + + gsm_dec_Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); + + gsm_dec_Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 13, wt, s ); + + gsm_dec_Coefficients_13_26( LARpp_j_1, LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 14, wt + 13, s + 13 ); + + gsm_dec_Coefficients_27_39( LARpp_j_1, LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 13, wt + 27, s + 27 ); + + gsm_dec_Coefficients_40_159( LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 120, wt + 40, s + 40 ); +} + +void gsm_dec_Coefficients_27_39( word *LARpp_j_1, word *LARpp_j, word *LARp ) +{ + int i; + longword ltmp; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++ ) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ) ); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ) ); + } +} + +/* + Initialization- and return-value-related functions +*/ + +gsm gsm_dec_create( void ) +{ + unsigned int i; + gsm r; + volatile char x = 0; + + r = &gsm_dec_state; + + _Pragma( "loopbound min 648 max 648" ) + for ( i = 0; i < sizeof( *r ); i++ ) + ( ( char * )r )[i] = 0 + x; + + r->nrp = 40; + + return r; +} + +void gsm_dec_init( void ) +{ + gsm_dec_state_ptr = gsm_dec_create(); +} + +int gsm_dec_return( void ) +{ + return gsm_dec_result; +} + +/* + Main functions +*/ + +/* gsm_decode.c */ +int gsm_dec_decode( gsm s, gsm_byte *c, gsm_signal *target ) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13 * 4]; + + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if ( ( ( *c >> 4 ) & 0x0F ) != GSM_MAGIC ) + return -1; + + LARc[0] = ( *c++ & 0xF ) << 2; /* 1 */ + LARc[0] |= ( *c >> 6 ) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = ( *c >> 3 ) & 0x1F; + LARc[3] = ( *c++ & 0x7 ) << 2; + LARc[3] |= ( *c >> 6 ) & 0x3; + LARc[4] = ( *c >> 2 ) & 0xF; + LARc[5] = ( *c++ & 0x3 ) << 2; + LARc[5] |= ( *c >> 6 ) & 0x3; + LARc[6] = ( *c >> 3 ) & 0x7; + LARc[7] = *c++ & 0x7; + Nc[0] = ( *c >> 1 ) & 0x7F; + bc[0] = ( *c++ & 0x1 ) << 1; + bc[0] |= ( *c >> 7 ) & 0x1; + Mc[0] = ( *c >> 5 ) & 0x3; + xmaxc[0] = ( *c++ & 0x1F ) << 1; + xmaxc[0] |= ( *c >> 7 ) & 0x1; + xmc[0] = ( *c >> 4 ) & 0x7; + xmc[1] = ( *c >> 1 ) & 0x7; + xmc[2] = ( *c++ & 0x1 ) << 2; + xmc[2] |= ( *c >> 6 ) & 0x3; + xmc[3] = ( *c >> 3 ) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = ( *c >> 5 ) & 0x7; + xmc[6] = ( *c >> 2 ) & 0x7; + xmc[7] = ( *c++ & 0x3 ) << 1; /* 10 */ + xmc[7] |= ( *c >> 7 ) & 0x1; + xmc[8] = ( *c >> 4 ) & 0x7; + xmc[9] = ( *c >> 1 ) & 0x7; + xmc[10] = ( *c++ & 0x1 ) << 2; + xmc[10] |= ( *c >> 6 ) & 0x3; + xmc[11] = ( *c >> 3 ) & 0x7; + xmc[12] = *c++ & 0x7; + Nc[1] = ( *c >> 1 ) & 0x7F; + bc[1] = ( *c++ & 0x1 ) << 1; + bc[1] |= ( *c >> 7 ) & 0x1; + Mc[1] = ( *c >> 5 ) & 0x3; + xmaxc[1] = ( *c++ & 0x1F ) << 1; + xmaxc[1] |= ( *c >> 7 ) & 0x1; + xmc[13] = ( *c >> 4 ) & 0x7; + xmc[14] = ( *c >> 1 ) & 0x7; + xmc[15] = ( *c++ & 0x1 ) << 2; + xmc[15] |= ( *c >> 6 ) & 0x3; + xmc[16] = ( *c >> 3 ) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = ( *c >> 5 ) & 0x7; + xmc[19] = ( *c >> 2 ) & 0x7; + xmc[20] = ( *c++ & 0x3 ) << 1; + xmc[20] |= ( *c >> 7 ) & 0x1; + xmc[21] = ( *c >> 4 ) & 0x7; + xmc[22] = ( *c >> 1 ) & 0x7; + xmc[23] = ( *c++ & 0x1 ) << 2; + xmc[23] |= ( *c >> 6 ) & 0x3; + xmc[24] = ( *c >> 3 ) & 0x7; + xmc[25] = *c++ & 0x7; + Nc[2] = ( *c >> 1 ) & 0x7F; + bc[2] = ( *c++ & 0x1 ) << 1; /* 20 */ + bc[2] |= ( *c >> 7 ) & 0x1; + Mc[2] = ( *c >> 5 ) & 0x3; + xmaxc[2] = ( *c++ & 0x1F ) << 1; + xmaxc[2] |= ( *c >> 7 ) & 0x1; + xmc[26] = ( *c >> 4 ) & 0x7; + xmc[27] = ( *c >> 1 ) & 0x7; + xmc[28] = ( *c++ & 0x1 ) << 2; + xmc[28] |= ( *c >> 6 ) & 0x3; + xmc[29] = ( *c >> 3 ) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = ( *c >> 5 ) & 0x7; + xmc[32] = ( *c >> 2 ) & 0x7; + xmc[33] = ( *c++ & 0x3 ) << 1; + xmc[33] |= ( *c >> 7 ) & 0x1; + xmc[34] = ( *c >> 4 ) & 0x7; + xmc[35] = ( *c >> 1 ) & 0x7; + xmc[36] = ( *c++ & 0x1 ) << 2; + xmc[36] |= ( *c >> 6 ) & 0x3; + xmc[37] = ( *c >> 3 ) & 0x7; + xmc[38] = *c++ & 0x7; + Nc[3] = ( *c >> 1 ) & 0x7F; + bc[3] = ( *c++ & 0x1 ) << 1; + bc[3] |= ( *c >> 7 ) & 0x1; + Mc[3] = ( *c >> 5 ) & 0x3; + xmaxc[3] = ( *c++ & 0x1F ) << 1; + xmaxc[3] |= ( *c >> 7 ) & 0x1; + xmc[39] = ( *c >> 4 ) & 0x7; + xmc[40] = ( *c >> 1 ) & 0x7; + xmc[41] = ( *c++ & 0x1 ) << 2; + xmc[41] |= ( *c >> 6 ) & 0x3; + xmc[42] = ( *c >> 3 ) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = ( *c >> 5 ) & 0x7; + xmc[45] = ( *c >> 2 ) & 0x7; + xmc[46] = ( *c++ & 0x3 ) << 1; + xmc[46] |= ( *c >> 7 ) & 0x1; + xmc[47] = ( *c >> 4 ) & 0x7; + xmc[48] = ( *c >> 1 ) & 0x7; + xmc[49] = ( *c++ & 0x1 ) << 2; + xmc[49] |= ( *c >> 6 ) & 0x3; + xmc[50] = ( *c >> 3 ) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + + gsm_dec_Decoder( s, LARc, Nc, bc, Mc, xmaxc, xmc, target ); + + return 0; +} + +void _Pragma( "entrypoint" ) gsm_dec_main( void ) +{ + gsm r; + unsigned i; + gsm_dec_result = 0; + + r = gsm_dec_state_ptr; + + _Pragma( "loopbound min 1 max 1" ) + for ( i = 0; i < SAMPLES; i++ ) { + if ( gsm_dec_decode( r, gsm_dec_gsmdata + i * sizeof( gsm_frame ), + gsm_dec_pcmdata + i * 160 ) ) { + gsm_dec_result = 1; + return; + } + } +} + +int main( int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsComplete> is a signed arithmetic shift right */ +#define SASR(x, by) ((x) >> (by)) + +/* Table 4.3b Quantization levels of the LTP gain quantizer +*/ +/* bc 0 1 2 3 */ +word gsm_dec_QLB[4] = { 3277, 11469, 21299, 32767 }; + +#endif /* GSM_DEC_PRIVATE_H */ diff --git a/all_pairs/source/gsm_enc/COPYRIGHT b/all_pairs/source/gsm_enc/COPYRIGHT new file mode 100644 index 0000000..eba0e52 --- /dev/null +++ b/all_pairs/source/gsm_enc/COPYRIGHT @@ -0,0 +1,16 @@ +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +Any use of this software is permitted provided that this notice is not +removed and that neither the authors nor the Technische Universitaet Berlin +are deemed to have made any representations as to the suitability of this +software for any purpose nor are held responsible for any defects of +this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + +As a matter of courtesy, the authors request to be informed about uses +this software has found, about bugs in this software, and about any +improvements that may be of general interest. + +Berlin, 28.11.1994 +Jutta Degener +Carsten Bormann diff --git a/all_pairs/source/gsm_enc/ChangeLog.txt b/all_pairs/source/gsm_enc/ChangeLog.txt new file mode 100644 index 0000000..4dbeeda --- /dev/null +++ b/all_pairs/source/gsm_enc/ChangeLog.txt @@ -0,0 +1,8 @@ +2017-06-28: +- Rename benchmark to gsm_enc. +- Add prefix 'gsm_enc_'. +- Introduce gsm_enc_init and gsm_enc_return functions. +- Rewrite negative shifts to avoid undefined behavior. +- Fix comparisons between signed and unsigned types. +- Remove unused variables and parameters. +- Fix memory corruption in gsm_enc_Short_term_analysis_filtering. diff --git a/all_pairs/source/gsm_enc/data.h b/all_pairs/source/gsm_enc/data.h new file mode 100644 index 0000000..e656335 --- /dev/null +++ b/all_pairs/source/gsm_enc/data.h @@ -0,0 +1,452 @@ +#ifndef DATA_H +#define DATA_H + +gsm_signal gsm_enc_pcmdata[] = { + (short)0x0000, (short)0x0000, (short)0x0010, (short)0x0010, (short)0x0010, (short)0x0020, (short)0x0020, (short)0x0018, + (short)0x0028, (short)0x0020, (short)0x0020, (short)0x0028, (short)0x0028, (short)0x0020, (short)0x0030, (short)0x0030, + (short)0x0028, (short)0x0010, (short)0x0008, (short)0x0000, (short)0x0050, (short)0x0060, (short)0x0058, (short)0x00D0, + (short)0x00E0, (short)0x00D0, (short)0x0118, (short)0x0128, (short)0x0118, (short)0x0128, (short)0x0110, (short)0x0100, + (short)0x00A0, (short)0x0058, (short)0x0048, (short)0x0058, (short)0x0060, (short)0x0058, (short)0x0050, (short)0x0048, + (short)0x0040, (short)0x0030, (short)0x0020, (short)0x0010, (short)0x0008, (short)0xFFF8, (short)0xFFE8, (short)0xFFE0, + (short)0xFFD8, (short)0xFFC8, (short)0xFFC0, (short)0xFFC0, (short)0xFF98, (short)0xFF78, (short)0xFF78, (short)0xFFC8, + (short)0x0000, (short)0x0010, (short)0x0040, (short)0x0060, (short)0x0068, (short)0x0078, (short)0x0078, (short)0x0070, + (short)0x00A8, (short)0x00C8, (short)0x00C8, (short)0x00E0, (short)0x00F0, (short)0x00E8, (short)0x00F8, (short)0x00F8, + (short)0x00F0, (short)0x00E0, (short)0x00C8, (short)0x00B8, (short)0x00E8, (short)0x0100, (short)0x00F8, (short)0x00E8, + (short)0x00D8, (short)0x00C0, (short)0x00A8, (short)0x0020, (short)0xFFC0, (short)0xFFA0, (short)0xFFA0, (short)0xFFA8, + (short)0xFFB0, (short)0xFFD0, (short)0xFFF8, (short)0x0000, (short)0x0020, (short)0x0030, (short)0x0030, (short)0x0030, + (short)0x0028, (short)0x0020, (short)0xFFF0, (short)0xFFD0, (short)0xFFC8, (short)0xFFC8, (short)0xFFD0, (short)0xFFD8, + (short)0xFFE8, (short)0xFFF8, (short)0xFFF8, (short)0x0008, (short)0x0018, (short)0x0018, (short)0x0078, (short)0x00B8, + (short)0x00C0, (short)0x0100, (short)0x0130, (short)0x0128, (short)0x0108, (short)0x00D8, (short)0x00C0, (short)0x0078, + (short)0x0038, (short)0x0020, (short)0x0020, (short)0x0000, (short)0xFFE0, (short)0xFFE0, (short)0xFFD8, (short)0xFFC8, + (short)0xFFC8, (short)0xFFA0, (short)0xFF88, (short)0xFF98, (short)0xFF80, (short)0xFF70, (short)0xFF80, (short)0xFF78, + (short)0xFF78, (short)0xFF90, (short)0xFF80, (short)0xFF78, (short)0xFF78, (short)0xFF50, (short)0xFF30, (short)0xFF50, + (short)0xFF38, (short)0xFF30, (short)0xFF40, (short)0xFF58, (short)0xFF70, (short)0xFF80, (short)0xFF50, (short)0xFF38, + (short)0xFF40, (short)0xFF18, (short)0xFF00, (short)0xFF08, (short)0xFF40, (short)0xFF68, (short)0xFF80, (short)0xFF88, + (short)0xFF88, (short)0xFF88, (short)0xFF88, (short)0xFFB8, (short)0xFFE0, (short)0xFFF0, (short)0xFFD0, (short)0xFFB8, + (short)0xFFB8, (short)0xFF90, (short)0xFF70, (short)0xFF70, (short)0xFF50, (short)0xFF40, (short)0xFF40, (short)0xFF58, + (short)0xFF70, (short)0xFF80, (short)0xFFC8, (short)0x0000, (short)0x0018, (short)0x0030, (short)0x0048, (short)0x0048, + (short)0x0028, (short)0x0008, (short)0xFFF8, (short)0xFFD8, (short)0xFFC8, (short)0xFFB8, (short)0xFF98, (short)0xFF78, + (short)0xFF70, (short)0xFFF0, (short)0x0058, (short)0x0088, (short)0x00B8, (short)0x00D0, (short)0x00D8, (short)0x00E8, + (short)0x0138, (short)0x0160, (short)0x0158, (short)0x0170, (short)0x0178, (short)0x0160, (short)0x0168, (short)0x0160, + (short)0x0140, (short)0x0118, (short)0x00F0, (short)0x00C8, (short)0x0098, (short)0x0078, (short)0x0060, (short)0x0018, + (short)0xFFC0, (short)0xFF90, (short)0xFF48, (short)0xFF00, (short)0xFEE8, (short)0xFEC8, (short)0xFEB8, (short)0xFEB8, + (short)0xFEA0, (short)0xFE88, (short)0xFE80, (short)0xFEB8, (short)0xFEF8, (short)0xFF38, (short)0xFFA0, (short)0xFFE8, + (short)0x0008, (short)0x0030, (short)0x0058, (short)0x0068, (short)0x0068, (short)0x0070, (short)0x0068, (short)0x0050, + (short)0x0040, (short)0x0040, (short)0x0020, (short)0x0000, (short)0xFFE8, (short)0xFFF0, (short)0xFFF8, (short)0xFFF8, + (short)0x0038, (short)0x0068, (short)0x0078, (short)0x0038, (short)0x0008, (short)0xFFF0, (short)0xFFE0, (short)0xFFD8, + (short)0xFFD8, (short)0xFFE0, (short)0xFFD0, (short)0xFFC8, (short)0x0000, (short)0x0030, (short)0x0048, (short)0x0068, + (short)0x0080, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0078, + (short)0x0098, (short)0x00B0, (short)0x00B8, (short)0x0098, (short)0x0070, (short)0x0058, (short)0x0060, (short)0x0078, + (short)0x00A8, (short)0x00B8, (short)0x00A8, (short)0x00A0, (short)0x0080, (short)0x0068, (short)0x0060, (short)0x0058, + (short)0x0048, (short)0x0030, (short)0x0038, (short)0x0038, (short)0x0030, (short)0x0050, (short)0x0058, (short)0x0060, + (short)0x0030, (short)0x0008, (short)0xFFF8, (short)0xFF90, (short)0xFF48, (short)0xFF28, (short)0xFF10, (short)0xFEF8, + (short)0xFEF0, (short)0xFED8, (short)0xFEB0, (short)0xFEB0, (short)0xFEA8, (short)0xFEB8, (short)0xFED8, (short)0xFEF8, + (short)0xFF10, (short)0xFF20, (short)0xFF40, (short)0xFF58, (short)0xFF80, (short)0xFFA0, (short)0xFFB8, (short)0xFFC8, + (short)0xFFD8, (short)0xFFE0, (short)0xFFF0, (short)0x0048, (short)0x0098, (short)0x00B0, (short)0x0068, (short)0x0018, + (short)0xFFF8, (short)0xFFE8, (short)0xFFF0, (short)0xFFF8, (short)0x0020, (short)0x0038, (short)0x0038, (short)0x0050, + (short)0x0068, (short)0x0070, (short)0x0068, (short)0x0060, (short)0x0060, (short)0x0038, (short)0x0020, (short)0x0018, + (short)0x0040, (short)0x0060, (short)0x0068, (short)0x0040, (short)0x0010, (short)0x0000, (short)0xFFB0, (short)0xFF78, + (short)0xFF70, (short)0xFF90, (short)0xFFA8, (short)0xFFC8, (short)0xFF98, (short)0xFF50, (short)0xFF50, (short)0xFF50, + (short)0xFF58, (short)0xFF68, (short)0xFF48, (short)0xFF20, (short)0xFF18, (short)0xFF38, (short)0xFF60, (short)0xFF70, + (short)0xFF80, (short)0xFF98, (short)0xFFA0, (short)0xFFB8, (short)0xFFD0, (short)0xFFE0, (short)0x0018, (short)0x0048, + (short)0x0058, (short)0x00B0, (short)0x00F8, (short)0x0108, (short)0x0118, (short)0x0120, (short)0x0118, (short)0x0130, + (short)0x0148, (short)0x0140, (short)0x0130, (short)0x0120, (short)0x0108, (short)0x0098, (short)0x0038, (short)0x0018, + (short)0xFFD0, (short)0xFF90, (short)0xFF80, (short)0xFF58, (short)0xFF38, (short)0xFF30, (short)0xFF48, (short)0xFF68, + (short)0xFF78, (short)0xFF88, (short)0xFFB8, (short)0xFFD8, (short)0xFFE8, (short)0xFFD8, (short)0xFFF0, (short)0x0010, + (short)0x0020, (short)0x0020, (short)0x0018, (short)0x0028, (short)0x0030, (short)0x0030, (short)0x0038, (short)0x0060, + (short)0x0080, (short)0x0080, (short)0x00B0, (short)0x00D8, (short)0x00D0, (short)0x00B8, (short)0x00A8, (short)0x00A8, + (short)0x00A0, (short)0x0090, (short)0x0078, (short)0x0070, (short)0x0068, (short)0x0048, (short)0x0018, (short)0x0008, + (short)0x0008, (short)0x0000, (short)0x0000, (short)0xFFE8, (short)0xFFB0, (short)0xFF90, (short)0xFF88, (short)0xFF70, + (short)0xFF60, (short)0xFF60, (short)0xFF90, (short)0xFFC0, (short)0xFFD0, (short)0xFFD8, (short)0xFFE0, (short)0xFFE8, + (short)0x0018, (short)0x0050, (short)0x0058, (short)0x0030, (short)0x0008, (short)0x0000, (short)0x0018, (short)0x0038, + (short)0x0038, (short)0x0048, (short)0x0050, (short)0x0050, (short)0x0020, (short)0x0000, (short)0xFFF8, (short)0xFFB0, + (short)0xFF70, (short)0xFF68, (short)0xFFB0, (short)0xFFE8, (short)0xFFF8, (short)0xFFF8, (short)0xFFF8, (short)0xFFF0, + (short)0x0030, (short)0x0070, (short)0x0090, (short)0x0098, (short)0x0098, (short)0x0090, (short)0x00A0, (short)0x00B0, + (short)0x00B8, (short)0x00C0, (short)0x00C0, (short)0x00A8, (short)0x0098, (short)0x0088, (short)0x0078, (short)0x0050, + (short)0x0030, (short)0x0020, (short)0xFFD8, (short)0xFF98, (short)0xFF88, (short)0xFF50, (short)0xFF20, (short)0xFF18, + (short)0xFEF8, (short)0xFEE0, (short)0xFEE8, (short)0xFE70, (short)0xFE08, (short)0xFE00, (short)0xFE48, (short)0xFE98, + (short)0xFEB8, (short)0xFEE8, (short)0xFF10, (short)0xFF28, (short)0xFF18, (short)0xFF10, (short)0xFF18, (short)0xFF48, + (short)0xFF70, (short)0xFF88, (short)0xFFE0, (short)0x0028, (short)0x0040, (short)0x0058, (short)0x0068, (short)0x0070, + (short)0x0078, (short)0x0070, (short)0x0068, (short)0x0068, (short)0x0078, (short)0x0080, (short)0x0080, (short)0x0088, + (short)0x0088, (short)0x0080, (short)0x0058, (short)0x0030, (short)0x0020, (short)0x0018, (short)0x0018, (short)0x0018, + (short)0x0050, (short)0x0090, (short)0x00A0, (short)0x0080, (short)0x0060, (short)0x0050, (short)0x0030, (short)0x0018, + (short)0x0010, (short)0x0028, (short)0x0038, (short)0x0038, (short)0x0018, (short)0xFFF8, (short)0xFFF0, (short)0x0000, + (short)0x0020, (short)0x0020, (short)0x0030, (short)0x0030, (short)0x0030, (short)0x0040, (short)0x0050, (short)0x0050, + (short)0x0050, (short)0x0048, (short)0x0048, (short)0x0048, (short)0x0048, (short)0x0048, (short)0x0078, (short)0x00A0, + (short)0x00A8, (short)0x00C0, (short)0x00C8, (short)0x00C0, (short)0x00D0, (short)0x00E0, (short)0x00D8, (short)0x00E8, + (short)0x00F0, (short)0x00E0, (short)0x0100, (short)0x0118, (short)0x0110, (short)0x0100, (short)0x00F0, (short)0x00D8, + (short)0x0090, (short)0x0048, (short)0x0028, (short)0x0020, (short)0x0020, (short)0x0020, (short)0x0038, (short)0x0050, + (short)0x0050, (short)0x0050, (short)0x0048, (short)0x0040, (short)0x0050, (short)0x0060, (short)0x0060, (short)0x0040, + (short)0xFFC0, (short)0xFF58, (short)0xFF40, (short)0xFF90, (short)0xFFE8, (short)0x0000, (short)0x0020, (short)0x0030, + (short)0x0030, (short)0x0068, (short)0x0098, (short)0x00A8, (short)0x0110, (short)0x0168, (short)0x0170, (short)0x0148, + (short)0x0118, (short)0x00F0, (short)0x00E8, (short)0x00E0, (short)0x00D0, (short)0x0098, (short)0x0060, (short)0x0040, + (short)0x0000, (short)0xFFD8, (short)0xFFD8, (short)0xFFC0, (short)0xFFB0, (short)0xFFB0, (short)0xFF78, (short)0xFF30, + (short)0xFF10, (short)0xFEF0, (short)0xFEE8, (short)0xFEF0, (short)0xFEC8, (short)0xFED0, (short)0xFEF8, (short)0xFF00, + (short)0xFF10, (short)0xFF20, (short)0xFF50, (short)0xFF78, (short)0xFF90, (short)0xFF80, (short)0xFF70, (short)0xFF70, + (short)0xFF80, (short)0xFF98, (short)0xFFA0, (short)0xFFB8, (short)0xFFD0, (short)0xFFD8, (short)0xFFF0, (short)0x0000, + (short)0x0008, (short)0x0028, (short)0x0048, (short)0x0058, (short)0x0078, (short)0x0070, (short)0x0058, (short)0x0068, + (short)0x0098, (short)0x00B8, (short)0x00D8, (short)0x00F0, (short)0x00F0, (short)0x00E8, (short)0x00F8, (short)0x0100, + (short)0x00D8, (short)0x00D0, (short)0x00C8, (short)0x00E8, (short)0x0100, (short)0x00F0, (short)0x00E0, (short)0x00C8, + (short)0x00B8, (short)0x00A0, (short)0x0078, (short)0x0058, (short)0x0038, (short)0x0020, (short)0x0010, (short)0x0010, + (short)0x0018, (short)0x0010, (short)0x0010, (short)0x0010, (short)0x0018, (short)0x0028, (short)0x0008, (short)0xFFE0, + (short)0xFFC8, (short)0xFF80, (short)0xFF48, (short)0xFF38, (short)0xFF40, (short)0xFF48, (short)0xFF48, (short)0xFF70, + (short)0xFF90, (short)0xFFA8, (short)0xFFB8, (short)0xFFC0, (short)0xFFC8, (short)0xFFC0, (short)0xFFC0, (short)0xFFC0, + (short)0xFFB0, (short)0xFFA0, (short)0xFFA0, (short)0xFFA0, (short)0xFFA8, (short)0xFFB0, (short)0xFF68, (short)0xFF28, + (short)0xFF08, (short)0xFEF8, (short)0xFEF8, (short)0xFEE8, (short)0xFEE0, (short)0xFED8, (short)0xFEA8, (short)0xFE98, + (short)0xFEA8, (short)0xFEA8, (short)0xFEA0, (short)0xFEA0, (short)0xFED0, (short)0xFF00, (short)0xFF30, (short)0xFF28, + (short)0xFF38, (short)0xFF58, (short)0xFF48, (short)0xFF40, (short)0xFF48, (short)0xFFB0, (short)0x0010, (short)0x0038, + (short)0x0028, (short)0x0010, (short)0x0008, (short)0x0050, (short)0x00A0, (short)0x00B8, (short)0x00A0, (short)0x0080, + (short)0x0070, (short)0x0090, (short)0x00B0, (short)0x00B0, (short)0x00B8, (short)0x00B8, (short)0x00B0, (short)0x00C0, + (short)0x00D0, (short)0x00C8, (short)0x00A0, (short)0x0068, (short)0x0038, (short)0xFFF0, (short)0xFFB0, (short)0xFF88, + (short)0xFF78, (short)0xFF68, (short)0xFF60, (short)0xFF90, (short)0xFFC0, (short)0xFFE0, (short)0x0000, (short)0x0020, + (short)0x0030, (short)0x00A0, (short)0x0110, (short)0x0138, (short)0x0140, (short)0x0148, (short)0x0148, (short)0x0110, + (short)0x00E8, (short)0x00C0, (short)0x00A0, (short)0x0088, (short)0x0068, (short)0x0008, (short)0xFFB0, (short)0xFF88, + (short)0xFF58, (short)0xFF30, (short)0xFF20, (short)0xFEF8, (short)0xFED8, (short)0xFED8, (short)0xFF00, (short)0xFF20, + (short)0xFF38, (short)0xFF50, (short)0xFF68, (short)0xFF88, (short)0xFFA0, (short)0xFFB8, (short)0x0020, (short)0x0080, + (short)0x00A0, (short)0x00D8, (short)0x0100, (short)0x0100, (short)0x0138, (short)0x0168, (short)0x0148, (short)0x0128, + (short)0x0120, (short)0x00F8, (short)0x00E8, (short)0x00E0, (short)0x00C0, (short)0x00A8, (short)0x00B0, (short)0x0098, + (short)0x0070, (short)0x0048, (short)0x0030, (short)0xFFD0, (short)0xFF60, (short)0xFF48, (short)0xFF10, (short)0xFEA8, + (short)0xFEA8, (short)0xFEC0, (short)0xFEC0, (short)0xFEE8, (short)0xFEB0, (short)0xFE58, (short)0xFE88, (short)0xFED0, + (short)0xFEB8, (short)0xFE48, (short)0xFE58, (short)0xFEE8, (short)0xFF28, (short)0xFF18, (short)0xFF60, (short)0x00A0, + (short)0x01A0, (short)0x0188, (short)0x0178, (short)0x0208, (short)0x0208, (short)0x0100, (short)0x0018, (short)0xFFE0, + (short)0xFEE0, (short)0xFD68, (short)0xFD00, (short)0xFD60, (short)0xFD70, (short)0xFDA8, (short)0xFF00, (short)0x00A0, + (short)0x0170, (short)0x0210, (short)0x02D8, (short)0x0310, (short)0x0218, (short)0x00A0, (short)0xFFA0, (short)0xFDF0, + (short)0xFBD8, (short)0xFB08, (short)0xF9C0, (short)0xF830, (short)0xF8D8, (short)0xFCC0, (short)0x0038, (short)0x01A0, + (short)0x0380, (short)0x0A18, (short)0x0F50, (short)0x0DB0, (short)0x0C30, (short)0x0E18, (short)0x0CA8, (short)0x0570, + (short)0xFF98, (short)0xFE38, (short)0xFBA0, (short)0xF700, (short)0xF5D0, (short)0xF7C8, (short)0xF9A8, (short)0xFB48, + (short)0xFBB0, (short)0xFC78, (short)0xFF00, (short)0xFE98, (short)0xFB20, (short)0xFA48, (short)0xFAC0, (short)0xF8C8, + (short)0xF6E0, (short)0xF9C0, (short)0xFE08, (short)0xFF80, (short)0x0428, (short)0x0B70, (short)0x0E18, (short)0x0D38, + (short)0x0D38, (short)0x0C28, (short)0x01D0, (short)0xF578, (short)0xF108, (short)0xFB50, (short)0x0498, (short)0x0428, + (short)0x0CE8, (short)0x2190, (short)0x29F0, (short)0x22E0, (short)0x1F68, (short)0x2050, (short)0x1810, (short)0x0710, + (short)0xFA98, (short)0xF438, (short)0xEE68, (short)0xE950, (short)0xEBC8, (short)0xF538, (short)0xFEB8, (short)0x0240, + (short)0x0460, (short)0x09D0, (short)0x0978, (short)0xFFF8, (short)0xF810, (short)0xF190, (short)0xE8D0, (short)0xE290, + (short)0xDF60, (short)0xDFF0, (short)0xE668, (short)0xEC20, (short)0xF138, (short)0xFAC0, (short)0x04F0, (short)0x08D0, + (short)0x08C8, (short)0x0B18, (short)0x09F8, (short)0x0230, (short)0xFA38, (short)0xFA68, (short)0xFC78, (short)0xF9B8, + (short)0xF850, (short)0xFEA8, (short)0x05B8, (short)0x0690, (short)0x02E8, (short)0x0268, (short)0x0498, (short)0xFCB0, + (short)0xF018, (short)0xEDF8, (short)0x0090, (short)0x0F48, (short)0x0C70, (short)0x1278, (short)0x27B8, (short)0x2EA0, + (short)0x21F8, (short)0x1920, (short)0x1918, (short)0x1530, (short)0x0638, (short)0xF858, (short)0xF720, (short)0xF9F8, + (short)0xF600, (short)0xF850, (short)0x0590, (short)0x0EE0, (short)0x1000, (short)0x10D8, (short)0x1460, (short)0x10F8, + (short)0x0500, (short)0xFBC0, (short)0xF7A8, (short)0xF250, (short)0xEC00, (short)0xEB30, (short)0xF1C8, (short)0xF920, + (short)0xFC90, (short)0x0190, (short)0x0A60, (short)0x0E80, (short)0x0DB0, (short)0x0AD8, (short)0x0690, (short)0x0168, + (short)0xFF20, (short)0xFBD0, (short)0xF6F8, (short)0xF660, (short)0xF680, (short)0xF5B0, (short)0xF7C0, (short)0xF120, + (short)0xEA90, (short)0xF030, (short)0xEC18, (short)0xE190, (short)0xE558, (short)0xFF20, (short)0x1090, (short)0x0C50, + (short)0x1248, (short)0x2788, (short)0x2AD0, (short)0x1628, (short)0x08F0, (short)0x0BA8, (short)0x0538, (short)0xEF48, + (short)0xE410, (short)0xEB10, (short)0xEF68, (short)0xEA28, (short)0xEC40, (short)0xFC18, (short)0x08A8, (short)0x0818, + (short)0x0778, (short)0x0858, (short)0x02F8, (short)0xF8E8, (short)0xF1F0, (short)0xEF40, (short)0xECD0, (short)0xE958, + (short)0xEA70, (short)0xF260, (short)0xFAF0, (short)0xFFA0, (short)0x04A0, (short)0x0CF8, (short)0x10F8, (short)0x0EA0, + (short)0x0D48, (short)0x0BE8, (short)0x05E0, (short)0x03B0, (short)0x0358, (short)0xFF18, (short)0xFB40, (short)0xF9B0, + (short)0xF9C0, (short)0xF7C0, (short)0xEE90, (short)0xEAA0, (short)0xEE00, (short)0xE888, (short)0xE200, (short)0xEF00, + (short)0x0948, (short)0x1400, (short)0x1270, (short)0x1D88, (short)0x2CD8, (short)0x2488, (short)0x0DA8, (short)0x04B8, + (short)0x0548, (short)0xF7B0, (short)0xE3F0, (short)0xE268, (short)0xEFF8, (short)0xF5A0, (short)0xF320, (short)0xFC68, + (short)0x0BF0, (short)0x0FA0, (short)0x0A50, (short)0x01F8, (short)0xFE60, (short)0xFC48, (short)0xF340, (short)0xEB28, + (short)0xED58, (short)0xF3C0, (short)0xF5B8, (short)0xF738, (short)0x00F8, (short)0x0C70, (short)0x0E90, (short)0x0DE8, + (short)0x1190, (short)0x12B0, (short)0x1058, (short)0x0B98, (short)0x0638, (short)0x0868, (short)0x0998, (short)0x02B0, + (short)0xFE50, (short)0x0120, (short)0x02A0, (short)0xFC90, (short)0xF810, (short)0xF9D0, (short)0xF818, (short)0xF290, + (short)0xF240, (short)0xF6D0, (short)0x0A48, (short)0x1AD8, (short)0x1840, (short)0x1C18, (short)0x2B18, (short)0x29F0, + (short)0x1608, (short)0x08B8, (short)0x0778, (short)0x0128, (short)0xF118, (short)0xE868, (short)0xEDA0, (short)0xF310, + (short)0xF248, (short)0xF558, (short)0x0058, (short)0x0970, (short)0x0688, (short)0x0108, (short)0xFD08, (short)0xF988, + (short)0xF558, (short)0xF0A0, (short)0xF0B0, (short)0xF540, (short)0xF6E8, (short)0xFCA0, (short)0x0758, (short)0x0CD0, + (short)0x0F60, (short)0x1338, (short)0x1458, (short)0x1278, (short)0x0FD0, (short)0x0CA8, (short)0x0D50, (short)0x0D10, + (short)0x0798, (short)0x0398, (short)0x0428, (short)0x04F0, (short)0x0278, (short)0xFF98, (short)0x0178, (short)0x0088, + (short)0xFB08, (short)0xF660, (short)0xF1A8, (short)0xEF18, (short)0xF9E8, (short)0x0C00, (short)0x11C8, (short)0x1260, + (short)0x1B60, (short)0x21B0, (short)0x18E0, (short)0x0B08, (short)0x04C8, (short)0x0078, (short)0xF730, (short)0xEF60, + (short)0xEB18, (short)0xEC10, (short)0xF290, (short)0xF800, (short)0xFB60, (short)0xFF60, (short)0x0080, (short)0xFFA8, + (short)0xFB08, (short)0xF1A8, (short)0xED10, (short)0xEFF0, (short)0xEED0, (short)0xEB10, (short)0xEFE8, (short)0xF8F0, + (short)0xFDE0, (short)0x0298, (short)0x0528, (short)0x0598, (short)0x0928, (short)0x0A30, (short)0x0670, (short)0x08E8, + (short)0x0BC0, (short)0x0698, (short)0x0210, (short)0x0390, (short)0x0560, (short)0x0288, (short)0xF910, (short)0xF468, + (short)0xF560, (short)0xF3E0, (short)0xEE10, (short)0xE8B0, (short)0xE508, (short)0xEED0, (short)0x03E0, (short)0x0638, + (short)0xFFA8, (short)0x0BB8, (short)0x2078, (short)0x1FA8, (short)0x0EF0, (short)0x0648, (short)0x05C8, (short)0xFF18, + (short)0xF588, (short)0xEE20, (short)0xED88, (short)0xF5A0, (short)0xFBA8, (short)0xFBC0, (short)0xFA98, (short)0xFA20, + (short)0xF7D8, (short)0xF2D0, (short)0xEF48, (short)0xE998, (short)0xE378, (short)0xE530, (short)0xE868, (short)0xE890, + (short)0xEDD0, (short)0xF798, (short)0xFBC0, (short)0xFD20, (short)0x0178, (short)0x0490, (short)0x04A0, (short)0x0758, + (short)0x0858, (short)0x0490, (short)0x04F8, (short)0x0858, (short)0x06F0, (short)0x05F8, (short)0x0450, (short)0x0098, + (short)0xFE60, (short)0xFDA0, (short)0xF9E0, (short)0xF358, (short)0xEDC0, (short)0xF308, (short)0xFFE0, (short)0x0018, + (short)0xFB80, (short)0x0948, (short)0x1DB8, (short)0x1D08, (short)0x0F88, (short)0x0B48, (short)0x0C50, (short)0x09C0, + (short)0xFF78, (short)0xF1A0, (short)0xEF28, (short)0xF6B8, (short)0xF9F0, (short)0xF6F0, (short)0xF688, (short)0xF9E0, + (short)0xF9C0, (short)0xF4C8, (short)0xEBD8, (short)0xE7E8, (short)0xEBE0, (short)0xE8C8, (short)0xE100, (short)0xE518, + (short)0xF0B8, (short)0xF728, (short)0xF770, (short)0xF878, (short)0xFF58, (short)0x06B0, (short)0x0430, (short)0x0060, + (short)0x0390, (short)0x0A18, (short)0x0B98, (short)0x06C8, (short)0x0710, (short)0x0CF0, (short)0x08D0, (short)0x01F8, + (short)0x0280, (short)0x0238, (short)0xFD78, (short)0xF868, (short)0xF198, (short)0xF670, (short)0x0930, (short)0x0A78, + (short)0xFB38, (short)0x04F0, (short)0x1EB8, (short)0x1E98, (short)0x0F68, (short)0x0EC8, (short)0x1548, (short)0x1480, + (short)0x0C60, (short)0x00B0, (short)0xFEF8, (short)0x0830, (short)0x0838, (short)0x0160, (short)0x0380, (short)0x07E8, + (short)0x0270, (short)0xFBA0, (short)0xF9C0, (short)0xF450, (short)0xEE08, (short)0xED08, (short)0xEE10, (short)0xEF20, + (short)0xF1C0, (short)0xF800, (short)0xFE70, (short)0x00B0, (short)0x02D8, (short)0x07C8, (short)0x09F0, (short)0x09A8, + (short)0x0A60, (short)0x0B28, (short)0x0C80, (short)0x0D58, (short)0x0BD0, (short)0x0A48, (short)0x0900, (short)0x0768, + (short)0x03D0, (short)0x00E0, (short)0xFFF8, (short)0xFBD8, (short)0xF5E8, (short)0xFE18, (short)0x0FE8, (short)0x1060, + (short)0x05C8, (short)0x1078, (short)0x2638, (short)0x2580, (short)0x1740, (short)0x14E8, (short)0x19D0, (short)0x17D8, + (short)0x0E10, (short)0x0270, (short)0x0120, (short)0x0900, (short)0x0870, (short)0x0290, (short)0x03A0, (short)0x0600, + (short)0x0100, (short)0xFE28, (short)0xFF28, (short)0xF838, (short)0xF0B8, (short)0xF238, (short)0xF530, (short)0xF440, + (short)0xF440, (short)0xFA38, (short)0x0198, (short)0x03A8, (short)0x03D0, (short)0x0780, (short)0x0AB8, (short)0x0B58, + (short)0x0B10, (short)0x0AD8, (short)0x0A08, (short)0x0878, (short)0x07C8, (short)0x0648, (short)0x01A0, (short)0xFF48, + (short)0xFE58, (short)0xFA68, (short)0xF7D0, (short)0xF758, (short)0xF470, (short)0xF5B0, (short)0x02A8, (short)0x0A58, + (short)0x0448, (short)0x07C8, (short)0x1708, (short)0x1970, (short)0x0EC8, (short)0x0A40, (short)0x0CD0, (short)0x0D28, + (short)0x0838, (short)0x0010, (short)0xFAE0, (short)0xFCB0, (short)0xFEB8, (short)0xFCE8, (short)0xFBA8, (short)0xFD10, + (short)0xFBC8, (short)0xF910, (short)0xF960, (short)0xF830, (short)0xF4D8, (short)0xF500, (short)0xF860, (short)0xF9F0, + (short)0xFB58, (short)0xFE48, (short)0x0050, (short)0x0418, (short)0x0910, (short)0x0940, (short)0x0830, (short)0x0AC8, + (short)0x0C88, (short)0x0A50, (short)0x07C0, (short)0x0700, (short)0x0590, (short)0x0268, (short)0xFFF0, (short)0xFBA8, + (short)0xF720, (short)0xF698, (short)0xF2E0, (short)0xEB68, (short)0xEDA0, (short)0xFC00, (short)0x0358, (short)0xFF30, + (short)0x0398, (short)0x1220, (short)0x1860, (short)0x1368, (short)0x10C0, (short)0x12F0, (short)0x12A0, (short)0x0E08, + (short)0x0780, (short)0x0010, (short)0xFAD8, (short)0xF990, (short)0xF7E0, (short)0xF278, (short)0xEE10, (short)0xEB98, + (short)0xE7A0, (short)0xE6F8, (short)0xEA30, (short)0xE980, (short)0xE420, (short)0xE440, (short)0xEBA8, (short)0xEF98, + (short)0xEF68, (short)0xF288, (short)0xF7A8, (short)0xFC90, (short)0x01F8, (short)0x0528, (short)0x0630, (short)0x08E8, + (short)0x0C98, (short)0x0D50, (short)0x0B98, (short)0x0920, (short)0x0678, (short)0x03F0, (short)0x0260, (short)0xFE00, + (short)0xF810, (short)0xF4B8, (short)0xF0C0, (short)0xEB68, (short)0xEF58, (short)0xFAE8, (short)0xFDE0, (short)0xF680, + (short)0xF910, (short)0x06E0, (short)0x0C20, (short)0x05D8, (short)0x0408, (short)0x05C8, (short)0x0450, (short)0x02D0, + (short)0x0128, (short)0xFB78, (short)0xF668, (short)0xF430, (short)0xF150, (short)0xED90, (short)0xE870, (short)0xE448, + (short)0xE2E0, (short)0xE048, (short)0xDDD0, (short)0xDF08, (short)0xE0E0, (short)0xE098, (short)0xE258, (short)0xE520, + (short)0xE6A8, (short)0xEA28, (short)0xEF88, (short)0xF2A8, (short)0xF548, (short)0xFBA8, (short)0x01C8, (short)0x03F8, + (short)0x0748, (short)0x0C88, (short)0x0E98, (short)0x0DB8, (short)0x0D98, (short)0x0D50, (short)0x0B68, (short)0x0970, + (short)0x06C0, (short)0x0238, (short)0xFE18, (short)0xFB08, (short)0xF820, (short)0xF780, (short)0xF970, (short)0xF9B0, + (short)0xF880, (short)0xFA28, (short)0x0028, (short)0x0698, (short)0x0948, (short)0x08D0, (short)0x09E0, (short)0x0DD0, + (short)0x1010, (short)0x0D40, (short)0x0958, (short)0x0728, (short)0x0308, (short)0xFDA0, (short)0xF9F8, (short)0xF418, + (short)0xEC98, (short)0xE8B8, (short)0xE618, (short)0xE200, (short)0xDED0, (short)0xDF48, (short)0xE100, (short)0xE180, + (short)0xE160, (short)0xE3C8, (short)0xE898, (short)0xEDD8, (short)0xF250, (short)0xF558, (short)0xFB00, (short)0x02F8, + (short)0x07B0, (short)0x0B80, (short)0x1108, (short)0x1518, (short)0x1660, (short)0x1770, (short)0x1870, (short)0x16F8, + (short)0x1300, (short)0x0F78, (short)0x0FC0, (short)0x1070, (short)0x0CE8, (short)0x0AF8, (short)0x0BD8, (short)0x0D28, + (short)0x10A8, (short)0x1370, (short)0x10A0, (short)0x1040, (short)0x1518, (short)0x1740, (short)0x1550, (short)0x1398, + (short)0x10E0, (short)0x0AC8, (short)0x0640, (short)0x0348, (short)0xFD18, (short)0xF658, (short)0xF1D8, (short)0xEC20, + (short)0xE760, (short)0xE550, (short)0xE4B8, (short)0xE418, (short)0xE438, (short)0xE508, (short)0xE738, (short)0xEB18, + (short)0xF0C8, (short)0xF618, (short)0xF988, (short)0xFEC8, (short)0x0518, (short)0x09D8, (short)0x1118, (short)0x17F0, + (short)0x1BB0, (short)0x1E28, (short)0x2120, (short)0x23D8, (short)0x2638, (short)0x2418, (short)0x2080, (short)0x1D30, + (short)0x1CE8, (short)0x1D98, (short)0x1CA8, (short)0x1AD8, (short)0x1960, (short)0x17F8, (short)0x1A40, (short)0x1CF8, + (short)0x1D38, (short)0x1C30, (short)0x1A68, (short)0x1860, (short)0x1480, (short)0x1020, (short)0x0B68, (short)0x03E8, + (short)0xFBA8, (short)0xF508, (short)0xEE40, (short)0xE820, (short)0xE338, (short)0xDE88, (short)0xDA30, (short)0xD7D0, + (short)0xD728, (short)0xD7D8, (short)0xD998, (short)0xDC10, (short)0xDFB0, (short)0xE470, (short)0xE948, (short)0xEF98, + (short)0xF5F0, (short)0xFC38, (short)0x0228, (short)0x0798, (short)0x0D98, (short)0x1320, (short)0x1760, (short)0x1A70, + (short)0x1BE0, (short)0x1CC0, (short)0x1D98, (short)0x1A88, (short)0x1658, (short)0x12A0, (short)0x1180, (short)0x10A8, + (short)0x0ED0, (short)0x0CC8, (short)0x0AD8, (short)0x0920, (short)0x0B70, (short)0x0E30, (short)0x0EE8, (short)0x0D80, + (short)0x0BE0, (short)0x0AC0, (short)0x09B8, (short)0x0890, (short)0x0690, (short)0x01F8, (short)0xFD30, (short)0xF9F0, + (short)0xF5B0, (short)0xF188, (short)0xEE38, (short)0xE9E8, (short)0xE5E8, (short)0xE3E0, (short)0xE4A0, (short)0xE608, + (short)0xE738, (short)0xE858, (short)0xE980, (short)0xEC20, (short)0xF030, (short)0xF450, (short)0xF878, (short)0xFC68, + (short)0xFF68, (short)0x03C8, (short)0x08B8, (short)0x0D00, (short)0x1038, (short)0x12D8, (short)0x1490, (short)0x1648, + (short)0x16B8, (short)0x1468, (short)0x1160, (short)0x0FA8, (short)0x1038, (short)0x1058, (short)0x0F88, (short)0x0E50, + (short)0x0CC8, (short)0x0CC0, (short)0x0FC0, (short)0x1220, (short)0x12A0, (short)0x10F8, (short)0x0F20, (short)0x0D28, + (short)0x0C78, (short)0x0BB8, (short)0x08D0, (short)0x01C8, (short)0xFB38, (short)0xF660, (short)0xF330, (short)0xF078, + (short)0xEC28, (short)0xE6C8, (short)0xE2C0, (short)0xE050, (short)0xDFC8, (short)0xE038, (short)0xE160, (short)0xE300, + (short)0xE568, (short)0xE6B8, (short)0xE9A0, (short)0xED50, (short)0xF238, (short)0xF6D8, (short)0xFB08, (short)0xFF10, + (short)0x02E8, (short)0x06A0, (short)0x0AC0, (short)0x0DC8, (short)0x1010, (short)0x1168, (short)0x1018, (short)0x0E90, + (short)0x0BF8, (short)0x0B08, (short)0x0A50, (short)0x09F0, (short)0x0960, (short)0x0888, (short)0x0808, (short)0x09C8, + (short)0x0BA8, (short)0x0EE8, (short)0x1070, (short)0x10D0, (short)0x0F58, (short)0x0D60, (short)0x0BA0, (short)0x0A60, + (short)0x08F0, (short)0x0608, (short)0xFFB0, (short)0xF938, (short)0xF360, (short)0xF030, (short)0xEE20, (short)0xEB70, + (short)0xE7A8, (short)0xE410, (short)0xE140, (short)0xDFC8, (short)0xDFF8, (short)0xE1F0, (short)0xE448, (short)0xE6D0, + (short)0xE780, (short)0xE9E8, (short)0xECF0, (short)0xF248, (short)0xF730, (short)0xFBC0, (short)0xFF80, (short)0x0310, + (short)0x0670, (short)0x0A98, (short)0x0D88, (short)0x0FD8, (short)0x10C0, (short)0x0EB0, (short)0x0C48, (short)0x08B8, + (short)0x0998, (short)0x0AC0, (short)0x0C68, (short)0x0B78, (short)0x09C8, (short)0x0838, (short)0x08F8, (short)0x0A80, + (short)0x0CA0, (short)0x0E10, (short)0x0E48, (short)0x0D58, (short)0x0A28, (short)0x0750, (short)0x04F0, (short)0x0228, + (short)0xFEE8, (short)0xFA80, (short)0xF468, (short)0xEED0, (short)0xEAE0, (short)0xE8B8, (short)0xE718, (short)0xE5B0, + (short)0xE4A8, (short)0xE410, (short)0xE480, (short)0xE548, (short)0xE738, (short)0xE9B0, (short)0xED80, (short)0xF0B8, + (short)0xF480, (short)0xF7B0, (short)0xFB70, (short)0xFED0, (short)0x0328, (short)0x0720, (short)0x0A98, (short)0x0E00, + (short)0x10F8, (short)0x12E0, (short)0x12A8, (short)0x11B0, (short)0x0F58, (short)0x0F38, (short)0x0E88, (short)0x0F08, + (short)0x0FC0, (short)0x0FF0, (short)0x10B8, (short)0x1138, (short)0x1198, (short)0x13D0, (short)0x1638, (short)0x17E8, + (short)0x1758, (short)0x1628, (short)0x1460, (short)0x10E8, (short)0x0CA0, (short)0x0848, (short)0x0280, (short)0xFC90, + (short)0xF700, (short)0xF0F8, (short)0xEB18, (short)0xE638, (short)0xE1B8, (short)0xDE78, (short)0xDC58, (short)0xDBB8, + (short)0xDC28, (short)0xDDB0, (short)0xE030, (short)0xE330, (short)0xE6F0, (short)0xEC20, (short)0xF210, (short)0xF7C0, + (short)0xFCE0, (short)0x0150, (short)0x0570, (short)0x08F0, (short)0x0C70, (short)0x0F50, (short)0x12B8, (short)0x1560, + (short)0x16E0, (short)0x1630, (short)0x14E8, (short)0x1298, (short)0x11B8, (short)0x1170, (short)0x11B8, (short)0x11C0, + (short)0x0FE8, (short)0x0E58, (short)0x0CB8, (short)0x0C50, (short)0x0D68, (short)0x0E98, (short)0x0E30, (short)0x0C28, + (short)0x0A10, (short)0x06D8, (short)0x02E0, (short)0xFEA0, (short)0xFA18, (short)0xF4E8, (short)0xF018, (short)0xEB68, + (short)0xE6E8, (short)0xE310, (short)0xDFC8, (short)0xDD38, (short)0xDBF8, (short)0xDC38, (short)0xDDD0, (short)0xE070, + (short)0xE390, (short)0xE760, (short)0xEB88, (short)0xEF20, (short)0xF378, (short)0xF830, (short)0xFCE0, (short)0x00F8, + (short)0x0480, (short)0x0768, (short)0x0968, (short)0x0AE0, (short)0x0BB8, (short)0x0C10, (short)0x0BB0, (short)0x0A78, + (short)0x08E0, (short)0x06E8, (short)0x0540, (short)0x0870, (short)0x0BE0, (short)0x0ED0, (short)0x0E40, (short)0x0D10, + (short)0x0CC8, (short)0x0E28, (short)0x0FA0, (short)0x0FB0, (short)0x0F18, (short)0x0DD0, (short)0x0BC8, (short)0x08E8, + (short)0x0628, (short)0x0300, (short)0xFF18, (short)0xFB40, (short)0xF780, (short)0xF388, (short)0xF028, (short)0xED80, + (short)0xEB18, (short)0xE968, (short)0xE8C0, (short)0xE738, (short)0xE658, (short)0xE698, (short)0xE888, (short)0xEB38, + (short)0xEDA0, (short)0xF178, (short)0xF5B8, (short)0xFA28, (short)0xFEA8, (short)0x0300, (short)0x06C8, (short)0x0960, + (short)0x0B70, (short)0x0CE0, (short)0x0D70, (short)0x0D50, (short)0x0C60, (short)0x0890, (short)0x0418, (short)0x0028, + (short)0x01D0, (short)0x03F8, (short)0x05A8, (short)0x0700, (short)0x0808, (short)0x09A0, (short)0x0B18, (short)0x0CC8, + (short)0x0D90, (short)0x0E68, (short)0x0EC0, (short)0x0E30, (short)0x0C28, (short)0x09D8, (short)0x0730, (short)0x0308, + (short)0xFED8, (short)0xFAC0, (short)0xF598, (short)0xF0D8, (short)0xECE0, (short)0xEAA8, (short)0xE948, (short)0xE8D0, + (short)0xE850, (short)0xE888, (short)0xE910, (short)0xEAD0, (short)0xED68, (short)0xF018, (short)0xF350, (short)0xF6B8, + (short)0xFAE0, (short)0xFF00, (short)0x02D8, (short)0x05E8, (short)0x0830, (short)0x09F8, (short)0x0B08, (short)0x0B80, + (short)0x0B60, (short)0x0988, (short)0x0648, (short)0x02D0, (short)0x0150, (short)0x01E8, (short)0x0270, (short)0x03E0, + (short)0x0538, (short)0x0658, (short)0x0918, (short)0x0C00, (short)0x0E88, (short)0x10B8, (short)0x12A0, (short)0x13E0, + (short)0x1488, (short)0x1448, (short)0x1368, (short)0x1120, (short)0x0DD0, (short)0x0A40, (short)0x0608, (short)0x0148, + (short)0xFC80, (short)0xF860, (short)0xF4D8, (short)0xF1C0, (short)0xF008, (short)0xEF38, (short)0xEE78, (short)0xEE98, + (short)0xEF90, (short)0xF170, (short)0xF390, (short)0xF5C0, (short)0xF888, (short)0xFB48, (short)0xFDF0, (short)0x0078, + (short)0x03D0, (short)0x06C8, (short)0x08F8, (short)0x0AA0, (short)0x0BC8, (short)0x0C48, (short)0x0B30, (short)0x0978, + (short)0x06A8, (short)0x0530, (short)0x03F0, (short)0x0438, (short)0x03C0, (short)0x0350, (short)0x0360, (short)0x04E8, + (short)0x0698, (short)0x07D0, (short)0x08D0, (short)0x0998, (short)0x0A70, (short)0x0B48, (short)0x0B70, (short)0x0AD0, + (short)0x09C0, (short)0x0890, (short)0x0730, (short)0x0588, (short)0x0358, (short)0x0140, (short)0xFF58, (short)0xFD40, + (short)0xFB68, (short)0xF9E8, (short)0xF828, (short)0xF6D0, (short)0xF608, (short)0xF5D8, (short)0xF610, (short)0xF668, + (short)0xF778, (short)0xF8E8, (short)0xFA48, (short)0xFCC8, (short)0xFF50, (short)0x01C8, (short)0x0428, (short)0x0640, + (short)0x07D0, (short)0x09D0, (short)0x0B40, (short)0x0BF8, (short)0x0C30, (short)0x0C08, (short)0x0B08, (short)0x0988, + (short)0x07C0, (short)0x0670, (short)0x0608, (short)0x0590, (short)0x0588, (short)0x05B0, (short)0x05E0, (short)0x06B8, + (short)0x0748, (short)0x0758, (short)0x0700, (short)0x06A8, (short)0x0620, (short)0x05D8, (short)0x0590, (short)0x0528, + (short)0x03A8, (short)0x0240, (short)0x0108, (short)0xFF38, (short)0xFD50, (short)0xFBA0, (short)0xFA38, (short)0xF920, + (short)0xF860, (short)0xF6E8, (short)0xF640, (short)0xF628, (short)0xF680, (short)0xF720, (short)0xF800, (short)0xF8E0, + (short)0xF9A0, (short)0xFA78, (short)0xFB88, (short)0xFD20, (short)0xFEA0, (short)0x0008, (short)0x0110, (short)0x0200, + (short)0x0360, (short)0x04E0, (short)0x0608, (short)0x0738, (short)0x0838, (short)0x08D8, (short)0x0828, (short)0x0738, + (short)0x0600, (short)0x04A8, (short)0x02E0, (short)0x0130, (short)0xFFA0, (short)0xFF48, (short)0xFF10, (short)0xFEF0, + (short)0xFF30, (short)0xFFD0, (short)0x0090, (short)0x0090, (short)0x0070, (short)0x0060, (short)0xFFE8, (short)0xFF50, + (short)0xFEB8, (short)0xFE98, (short)0xFE88, (short)0xFE80, (short)0xFE58, (short)0xFE50, (short)0xFE58, (short)0xFDB0, + (short)0xFD08, (short)0xFC80, (short)0xFAF8, (short)0xF988, (short)0xF860, (short)0xF798, (short)0xF720, (short)0xF6E8, + (short)0xF728, (short)0xF7C0, (short)0xF8A8, (short)0xF8F8, (short)0xF960, (short)0xFA18, (short)0xFAC0, (short)0xFB58, + (short)0xFC18, (short)0xFCE0, (short)0xFDA0, (short)0xFE20, (short)0xFE88, (short)0xFEF8, (short)0xFEF0, (short)0xFEC8, + (short)0xFEA8, (short)0xFDE0, (short)0xFD10, (short)0xFC70, (short)0xFBA8, (short)0xFB10, (short)0xFAB8, (short)0xFAA0, + (short)0xFAD0, (short)0xFB18, (short)0xFA90, (short)0xFA18, (short)0xFA10, (short)0xFA80, (short)0xFB10, (short)0xFB88, + (short)0xFC90, (short)0xFDB8, (short)0xFEB8, (short)0xFF80, (short)0x0058, (short)0x0138, (short)0x0118, (short)0x00C8, + (short)0x00C0, (short)0xFF98, (short)0xFE30, (short)0xFD38, (short)0xFC68, (short)0xFB78, (short)0xFAB8, (short)0xFAE8, + (short)0xFB78, (short)0xFBD0, (short)0xFBE8, (short)0xFC18, (short)0xFC98, (short)0xFD28, (short)0xFD48, (short)0xFD68, + (short)0xFD68, (short)0xFD90, (short)0xFDB8, (short)0xFD90, (short)0xFD68, (short)0xFD78, (short)0xFCA0, (short)0xFB70, + (short)0xFAD0, (short)0xF9F0, (short)0xF870, (short)0xF748, (short)0xF748, (short)0xF770, (short)0xF748, (short)0xF720, + (short)0xF7A8, (short)0xF878, (short)0xF930, (short)0xF998, (short)0xFA38, (short)0xFC10, (short)0xFDA0, (short)0xFE70, + (short)0x0030, (short)0x0248, (short)0x03A0, (short)0x0568, (short)0x0738, (short)0x0870, (short)0x0960, (short)0x0A10, + (short)0x0A40, (short)0x0A28, (short)0x09B8, (short)0x08E8, (short)0x07E8, (short)0x06E0, (short)0x0588, (short)0x0430, + (short)0x0300, (short)0x0260, (short)0x01D0, (short)0x0118, (short)0xFFB0, (short)0xFE98, (short)0xFE18, (short)0xFDA0, + (short)0xFD08, (short)0xFCB8, (short)0xFCF8, (short)0xFD60, (short)0xFD90, (short)0xFD90, (short)0xFDD8, (short)0xFE50, + (short)0xFDA0, (short)0xFCE0, (short)0xFCC0, (short)0xFCE8, (short)0xFCB0, (short)0xFC60, (short)0xFC70, (short)0xFCB8, + (short)0xFCE0, (short)0xFD40, (short)0xFDD8, (short)0xFE68, (short)0xFF78, (short)0x0068, (short)0x0108, (short)0x0278, + (short)0x03A0, (short)0x0420, (short)0x0590, (short)0x0708, (short)0x07B8, (short)0x07D8, (short)0x0808, (short)0x0838, + (short)0x07D8, (short)0x06E8, (short)0x0600, (short)0x05B0, (short)0x0518, (short)0x0410, (short)0x02A0, (short)0x0198, + (short)0x00D0, (short)0x00C8, (short)0x00B0, (short)0x0068, (short)0x00C0, (short)0x0150, (short)0x0180, (short)0x0220, + (short)0x02D8, (short)0x0340, (short)0x0360, (short)0x0380, (short)0x0380, (short)0x0338, (short)0x02C8, (short)0x02B8, + (short)0x0280, (short)0x0200, (short)0x0100, (short)0x0098, (short)0x0080, (short)0x0020, (short)0xFFF0, (short)0x0000, + (short)0x0020, (short)0x0098, (short)0x0120, (short)0x0170, (short)0x0230, (short)0x02F0, (short)0x0350, (short)0x0480, + (short)0x05B8, (short)0x0650, (short)0x06A8, (short)0x0738, (short)0x0798, (short)0x07B0, (short)0x07C0, (short)0x0798, + (short)0x0668, (short)0x0598, (short)0x0530, (short)0x04C8, (short)0x0410, (short)0x0350, (short)0x0278, (short)0x01D8, + (short)0x0148, (short)0x0080, (short)0x0000, (short)0xFFC0, (short)0xFFD8, (short)0xFFA8, (short)0xFF60, (short)0xFF80, + (short)0x0018, (short)0x0070, (short)0xFFE0, (short)0xFF88, (short)0xFFC0, (short)0xFF38, (short)0xFE98, (short)0xFE50, + (short)0xFE10, (short)0xFDD8, (short)0xFD90, (short)0xFD30, (short)0xFDB8, (short)0xFE68, (short)0xFE70, (short)0xFE60, + (short)0xFE70, (short)0xFED0, (short)0xFF90, (short)0xFFE0, (short)0xFFF0, (short)0x00A8, (short)0x0168, (short)0x01D0, + (short)0x01F8, (short)0x0210, (short)0x0278, (short)0x0268, (short)0x0208, (short)0x0220, (short)0x01F8, (short)0x0198, + (short)0x0158, (short)0x0100, (short)0x00C0, (short)0x00A0, (short)0x0018, (short)0xFF98, (short)0xFF28, (short)0xFEC0, + (short)0xFE80, (short)0xFE60, (short)0xFD88, (short)0xFCF0, (short)0xFCC8, (short)0xFC70, (short)0xFC10, (short)0xFBC8, + (short)0xFBB0, (short)0xFBE8, (short)0xFBE8, (short)0xFB80, (short)0xFB88, (short)0xFB40, (short)0xFB18, (short)0xFB20, + (short)0xFAB8, (short)0xFA50, (short)0xFA50, (short)0xFAB8, (short)0xFAF8, (short)0xFB18, (short)0xFBB0, (short)0xFC88, + (short)0xFD10, (short)0xFD40, (short)0xFD98, (short)0xFE38, (short)0xFEE0, (short)0xFEF8, (short)0xFEF0, (short)0xFF18, + (short)0xFF18, (short)0xFF18, (short)0xFF68, (short)0xFF98, (short)0xFF98, (short)0xFFD0, (short)0xFFF8, (short)0x0048, + (short)0x0038, (short)0x0008, (short)0x0008, (short)0xFFE0, (short)0xFFB0, (short)0xFFB8, (short)0xFED0, (short)0xFE18, + (short)0xFE18, (short)0xFDF0, (short)0xFE38, (short)0xFE90, (short)0xFE90, (short)0xFDA8, (short)0xFD48, (short)0xFD70, + (short)0xFD68, (short)0xFD00, (short)0xFCB8, (short)0xFCB8, (short)0xFCF8, (short)0xFD00, (short)0xFC30, (short)0xFBD0, + (short)0xFC10, (short)0xFC20, (short)0xFBE0, (short)0xFBA8, (short)0xFC30, (short)0xFD00, (short)0xFD50, (short)0xFD90, + (short)0xFE10, (short)0xFEA8, (short)0xFF40, (short)0xFFA0, (short)0xFFD0, (short)0xFFC8, (short)0xFFC8, (short)0xFFD8, + (short)0xFFA0, (short)0xFF98, (short)0xFFB8, (short)0x0050, (short)0x00B8, (short)0x00B0, (short)0x01B0, (short)0x02E0, + (short)0x0318, (short)0x0330, (short)0x02E0, (short)0x02C8, (short)0x0278, (short)0x0150, (short)0x0050, (short)0xFFC0, + (short)0xFF88, (short)0xFF18, (short)0xFE90, (short)0xFE40, (short)0xFE30, (short)0xFDE8, (short)0xFDD0, (short)0xFD70, + (short)0xFD48, (short)0xFD10, (short)0xFC98, (short)0xFC38, (short)0xFC38, (short)0xFC78, (short)0xFC98, (short)0xFCF0, + (short)0xFDA8, (short)0xFE48, (short)0xFEC8, (short)0xFF30, (short)0xFF98, (short)0x0000, (short)0x0050, (short)0x0058, + (short)0x00A8, (short)0x00E8, (short)0x00D0, (short)0x0138, (short)0x01E0, (short)0x0218, (short)0x0208, (short)0x0230, + (short)0x0258, (short)0x0248, (short)0x02B0, (short)0x0318, (short)0x0330, (short)0x0358, (short)0x0380, (short)0x0378, + (short)0x0408, (short)0x0480, (short)0x0460, (short)0x03C8, (short)0x0318, (short)0x02B0, (short)0x01E8, (short)0x00B8, + (short)0xFFD8, (short)0xFF30, (short)0xFEC8, (short)0xFE60, (short)0xFE60, (short)0xFE78, (short)0xFE78, (short)0xFDC0, + (short)0xFD70, (short)0xFD50, (short)0xFD08, (short)0xFC88, (short)0xFC28, (short)0xFC98, (short)0xFD18, (short)0xFD60, + (short)0xFD60, (short)0xFDD8, (short)0xFE90, (short)0xFEE8, (short)0xFF10, (short)0xFF58, (short)0xFF90, (short)0xFFB8, + (short)0xFFE0, (short)0xFFF0, (short)0xFFF0, (short)0x00D0, (short)0x0190, (short)0x01C8, (short)0x0180, (short)0x0188, + (short)0x01B0, (short)0x0238, (short)0x0298, (short)0x02B8, (short)0x0268, (short)0x0258, (short)0x0258, (short)0x0230, + (short)0x0228, (short)0x0230, (short)0x0258, (short)0x0248, (short)0x01F8, (short)0x0150, (short)0x00C8, (short)0x0058, + (short)0x0058, (short)0x0038, (short)0x0000, (short)0xFF50, (short)0xFF00, (short)0xFEF8, (short)0xFE80, (short)0xFDB8, + (short)0xFD70, (short)0xFD00, (short)0xFC90, (short)0xFC40, (short)0xFC28, (short)0xFC58, (short)0xFC98, (short)0xFD10, + (short)0xFD78, (short)0xFDE0, (short)0xFE80, (short)0xFF08, (short)0xFF60, (short)0xFFD0, (short)0x0030, (short)0x0068, + (short)0x0110, (short)0x0198, (short)0x01C0, (short)0x0208, (short)0x0260, (short)0x0280, (short)0x0320, (short)0x0390, + (short)0x0398, (short)0x0410, (short)0x0488, (short)0x04A0, (short)0x0448, (short)0x0408, (short)0x03E0, (short)0x03C8, + (short)0x0398, (short)0x0350, (short)0x0308, (short)0x02C8, (short)0x0278, (short)0x01D8, (short)0x0148, (short)0x00E8, + (short)0x0040, (short)0xFFA0, (short)0xFF50, (short)0xFDC0, (short)0xFC88, (short)0xFC30, (short)0xFB88, (short)0xFAA8, + (short)0xFA50, (short)0xFA30, (short)0xFA40, (short)0xFA70, (short)0xFAB8, (short)0xFAE0, (short)0xFB28, (short)0xFB58, + (short)0xFB80, (short)0xFBB0, (short)0xFC00, (short)0xFC80, (short)0xFCF0, (short)0xFDB8, (short)0xFE58, (short)0xFED8, + (short)0x0008, (short)0x0100, (short)0x0180, (short)0x01D0, (short)0x0210, (short)0x0248, (short)0x0238, (short)0x0200, + (short)0x01D0, (short)0x02D0, (short)0x03A0, (short)0x03D8, (short)0x03C0, (short)0x03D8, (short)0x03F8, (short)0x0370, + (short)0x02C0, (short)0x0258, (short)0x01B8, (short)0x0120, (short)0x0090, (short)0x0088, (short)0x00A8, (short)0x00A8, + (short)0x0088, (short)0x0068, (short)0x0060, (short)0xFFE0, (short)0xFF00, (short)0xFE50, (short)0xFDC8, (short)0xFCF0, + (short)0xFC30, (short)0xFBB0, (short)0xFBD8, (short)0xFC20, (short)0xFC58, (short)0xFC30, (short)0xFC40, (short)0xFC78, + (short)0xFCC0, (short)0xFCE8, (short)0xFD10, (short)0xFD48, (short)0xFD88, (short)0xFDE8, (short)0xFF10, (short)0x0020, + (short)0x0110, (short)0x01B8, (short)0x0248, (short)0x02C0, (short)0x0358, (short)0x03B8, (short)0x03C8, (short)0x0320, + (short)0x0288, (short)0x0280, (short)0x0300, (short)0x0340, (short)0x0320, (short)0x0380, (short)0x03F8, (short)0x0418, + (short)0x0378, (short)0x02E0, (short)0x0288, (short)0x0280, (short)0x0238, (short)0x01D0, (short)0x0168, (short)0x0138, + (short)0x0110, (short)0x0140, (short)0x0148, (short)0x0150, (short)0x00A8, (short)0x0010, (short)0xFFB0, (short)0xFEB8, + (short)0xFDE0, (short)0xFD48, (short)0xFCE8, (short)0xFCA8, (short)0xFC78, (short)0xFC48, (short)0xFC50, (short)0xFC70, + (short)0xFCA8, (short)0xFCE8, (short)0xFD28, (short)0xFDD0, (short)0xFE70, (short)0xFED8, (short)0x0040, (short)0x0188, + (short)0x0258, (short)0x03C0, (short)0x04F0, (short)0x05B8, (short)0x0638, (short)0x0670, (short)0x0690, (short)0x0708, + (short)0x0708, (short)0x06B8, (short)0x0660, (short)0x0650, (short)0x0630, (short)0x05C8, (short)0x0578, (short)0x0548, + (short)0x0508, (short)0x0470, (short)0x03D0, (short)0x0350, (short)0x0278, (short)0x01A0, (short)0x00F8, (short)0x00B0, + (short)0x0078, (short)0x0030, (short)0xFFE8, (short)0xFFC8, (short)0xFFB8, (short)0xFED0, (short)0xFE08, (short)0xFD98, + (short)0xFC70, (short)0xFB60, (short)0xFAA8, (short)0xFA10, (short)0xF9B8, (short)0xF980, (short)0xF9A0, (short)0xFA00, + (short)0xFA68, (short)0xFB90, (short)0xFCB8, (short)0xFD98, (short)0xFE68, (short)0xFF18, (short)0xFFC0, (short)0x0078, + (short)0x00F8, (short)0x0218, (short)0x0320, (short)0x03C0, (short)0x0478, (short)0x0510, (short)0x0570, (short)0x05D8, + (short)0x05E0, (short)0x05B8, (short)0x0508, (short)0x0468, (short)0x03E0, (short)0x02F0, (short)0x0218, (short)0x0168, + (short)0x00F0, (short)0x0060, (short)0xFFD0, (short)0xFF58, (short)0xFEC0, (short)0xFE48, (short)0xFDB0, (short)0xFD58, + (short)0xFD38, (short)0xFCD8, (short)0xFC80, (short)0xFC50, (short)0xFC08, (short)0xFB48, (short)0xFA98, (short)0xF9F8, + (short)0xF8F8, (short)0xF810, (short)0xF7F8, (short)0xF818, (short)0xF848, (short)0xF8E8, (short)0xF9E0, (short)0xFB08, + (short)0xFC38, (short)0xFD10, (short)0xFDE8, (short)0xFF10, (short)0xFFD0, (short)0x0048, (short)0x00E0, (short)0x0160, + (short)0x01B8, (short)0x01C8, (short)0x01E0, (short)0x0200, (short)0x0228, (short)0x0240, (short)0x0240, (short)0x0240, + (short)0x0260, (short)0x0280, (short)0x0280, (short)0x02F0, (short)0x0370, (short)0x03C8, (short)0x03C8, (short)0x03A8, + (short)0x03A0, (short)0x02F8, (short)0x0220, (short)0x0150, (short)0x0098, (short)0xFFE0, (short)0xFF20, (short)0xFEA0, + (short)0xFE50, (short)0xFE18, (short)0xFD38, (short)0xFC60, (short)0xFBE0, (short)0xFAC8, (short)0xF9A0, (short)0xF8B8, + (short)0xF830, (short)0xF888, (short)0xF8B8, (short)0xF908, (short)0xFA80, (short)0xFBF8, (short)0xFD48, (short)0xFEC8, + (short)0x0040, (short)0x01B0, (short)0x0298, (short)0x0338, (short)0x03C0, (short)0x0470, (short)0x0520, (short)0x0588, + (short)0x0610, (short)0x0688, (short)0x06C8, (short)0x0670, (short)0x05E8, (short)0x0578, (short)0x0580, (short)0x0578, + (short)0x0528, (short)0x0498, (short)0x0408, (short)0x0390, (short)0x03F8, (short)0x0458, (short)0x0488, (short)0x0468, + (short)0x0450, (short)0x0458, (short)0x03A8, (short)0x02D0, (short)0x0210, (short)0x0158, (short)0x0088, (short)0xFFA8, + (short)0xFF00, (short)0xFE88, (short)0xFE30, (short)0xFD88, (short)0xFCB8, (short)0xFC28, (short)0xFB30, (short)0xF9F0, + (short)0xF8E8, (short)0xF890, (short)0xF890, (short)0xF8C0, (short)0xF978, (short)0xFA78, (short)0xFBE8, (short)0xFD20, + (short)0xFE28, (short)0xFF60, (short)0x00D8, (short)0x0220, (short)0x02F8, (short)0x0378, (short)0x03E0, (short)0x0438, + (short)0x0488, (short)0x0498, (short)0x04A8, (short)0x0480, (short)0x0440, (short)0x03C0, (short)0x02D8, (short)0x01E8, + (short)0x0140, (short)0x00D8, (short)0x0068, (short)0xFFE0, (short)0x0068, (short)0x0130, (short)0x0228, (short)0x0260, + (short)0x0278, (short)0x02D0, (short)0x02D8, (short)0x0290, (short)0x01E0, (short)0x00D0, (short)0xFFE0, (short)0xFEF8, + (short)0xFE08, (short)0xFD28, (short)0xFC88, (short)0xFBE0, (short)0xFB60, (short)0xFAD8, (short)0xFA08, (short)0xF978, + (short)0xF8E8, (short)0xF8B0, (short)0xF8B0, (short)0xF8D0, (short)0xF9D0, (short)0xFAF8, (short)0xFC18, (short)0xFDB0, + (short)0xFF38, (short)0x00A0, (short)0x01F8, (short)0x02F8, (short)0x03C0, (short)0x0460, (short)0x04B8, (short)0x04C8, + (short)0x04C8, (short)0x04C0, (short)0x0498, (short)0x0490, (short)0x0478, (short)0x0448, (short)0x0420, (short)0x03F8, + (short)0x0328, (short)0x0238, (short)0x01B0, (short)0x0170, (short)0x0128, (short)0x0090, (short)0x00E8, (short)0x01B8, + (short)0x02B8, (short)0x0280, (short)0x0218, (short)0x0218, (short)0x01F0, (short)0x0148, (short)0x0000, (short)0xFEC0, + (short)0xFE08, (short)0xFD70, (short)0xFCA0, (short)0xFBF0, (short)0xFBC0, (short)0xFBA0, (short)0xFB80, (short)0xFB18, + (short)0xFB28, (short)0xFB98, (short)0xFBC0, (short)0xFBD0, (short)0xFC08, (short)0xFC78, (short)0xFDC8, (short)0xFEC8, + (short)0xFF78, (short)0x00D0, (short)0x0238, (short)0x0360, (short)0x0398, (short)0x0360, (short)0x0368, (short)0x0380, + (short)0x0318, (short)0x0250, (short)0x0208, (short)0x0220, (short)0x0218, (short)0x01F0, (short)0x01C8, (short)0x0210, + (short)0x0270, (short)0x0270, (short)0x0240, (short)0x0290, (short)0x0310, (short)0x0360, (short)0x0340, (short)0x0310, + (short)0x0318, (short)0x0320, (short)0x02D8, (short)0x0240, (short)0x0158, (short)0x00A0, (short)0x0008, (short)0xFF30, + (short)0xFE50, (short)0xFDA8, (short)0xFD28, (short)0xFCC8, (short)0xFC60, (short)0xFBA8, (short)0xFB40, (short)0xFB10, + (short)0xFB18, (short)0xFB28, (short)0xFB48, (short)0xFB68, (short)0xFBA8, (short)0xFBF8, (short)0xFCB8, (short)0xFD78, + (short)0xFE00, (short)0xFE88, (short)0xFF30, (short)0xFF98, (short)0xFFC8, (short)0xFFE8, (short)0x0050, (short)0x00B0, + (short)0x00E0, (short)0x0040, (short)0xFF68, (short)0xFED8, (short)0xFEE8, (short)0xFEE0, (short)0xFE90, (short)0xFEA8, + (short)0xFF88, (short)0x0080, (short)0x0188, (short)0x0208, (short)0x0290, (short)0x0390, (short)0x0438, (short)0x0450, + (short)0x0428, (short)0x03F8, (short)0x03E0, (short)0x0388, (short)0x02E0, (short)0x0240, (short)0x0190, (short)0x00D0, + (short)0x0000, (short)0x0000, (short)0x0018, (short)0x00FF, (short)0x0068, (short)0x00FE, (short)0x00F8, (short)0x00FD +}; + +gsm_byte gsm_enc_gsmdata[] = { + 0xD5, 0x1F, 0x74, 0x21, 0xA0, 0x50, 0x40, 0xC9, 0x24, 0x7B, 0xFA, 0x6B, 0x52, 0xE0, 0xB6, 0xD6, + 0x8E, 0xB9, 0x2B, 0xAE, 0xE0, 0x8B, 0x23, 0x52, 0x3B, 0x13, 0x86, 0xE0, 0x14, 0x4A, 0x41, 0x44, + 0x32, 0xD3, 0xA1, 0x83, 0xA1, 0x1D, 0xA6, 0x80, 0xBA, 0xD2, 0x96, 0x26, 0xFB, 0x84, 0x80, 0x6D, + 0x9C, 0x25, 0x1D, 0x9B, 0xAA, 0xC0, 0xBB, 0x4C, 0x95, 0xB9, 0x53, 0xAE, 0xA0, 0xB6, 0xE4, 0x46, + 0x37, 0x1B, 0xD4, 0xA5, 0x7B, 0x1D, 0x22, 0x97, 0x00, 0xBA, 0xA5, 0x6D, 0xD2, 0xA1, 0x7E, 0xC0, + 0xB9, 0x25, 0xD2, 0xB4, 0x94, 0x9E, 0xE0, 0x3E, 0xDE, 0xED, 0xD6, 0xD2, 0xE2, 0xC0, 0xD7, 0x5D, + 0x8D, 0x59, 0xAC, 0xD3, 0xE4, 0x83, 0x95, 0x59, 0xC0, 0xA1, 0x48, 0xD2, 0x66, 0xC7, 0x2C, 0x9E, + 0xA0, 0x2A, 0xD3, 0xEE, 0x45, 0x1C, 0x80, 0xE0, 0x6B, 0x34, 0x8C, 0x4B, 0x29, 0xCB, 0x00, 0xBA, + 0xF6, 0x0D, 0x26, 0x9A, 0xD3, 0xA4, 0x82, 0x9D, 0x63, 0x7A, 0xC0, 0x67, 0x24, 0xBA, 0xD6, 0x7C, + 0xC2, 0xC0, 0x37, 0x20, 0x4F, 0x10, 0xE0, 0xC7, 0x80, 0x6A, 0x77, 0x63, 0xBE, 0x6B, 0x5A, 0xC0, + 0xB5, 0x34, 0xD1, 0x34, 0x9C, 0xD4, 0xE8, 0x56, 0xB2, 0x58, 0x5F, 0x00, 0xB7, 0xAF, 0x92, 0x12, + 0x90, 0xD5, 0xA4, 0x39, 0x23, 0x4E, 0x46, 0x87, 0x51, 0xAC, 0xD8, 0xDB, 0x6D, 0xCB, 0x17, 0x50, + 0x89, 0x7B, 0x44, 0x28, 0x03, 0x6B, 0xD5, 0xA9, 0x36, 0x36, 0xD9, 0x6B, 0xA8, 0x93, 0x3A, 0x96, + 0xEE, 0xFF, 0x67, 0x8B, 0x36, 0xDA, 0x09, 0xB4, 0x99, 0x67, 0x2B, 0x88, 0xE4, 0xB5, 0xA5, 0xDA, + 0x65, 0x47, 0xDA, 0x1E, 0x96, 0xFA, 0xEC, 0xD5, 0xA9, 0x45, 0x63, 0x1A, 0xCB, 0xC9, 0x48, 0x9D, + 0x83, 0x5F, 0x6F, 0xCB, 0x08, 0x1B, 0x97, 0xC9, 0x18, 0x0A, 0x63, 0xCB, 0xA6, 0xE1, 0x84, 0xF5, + 0x62, 0x61, 0x6A, 0x84, 0xDC, 0xB6, 0x37, 0x9E, 0xD6, 0xAB, 0x3C, 0x53, 0x93, 0xC1, 0x2A, 0xAA, + 0x81, 0x8D, 0x6B, 0x65, 0x60, 0xA8, 0xFB, 0x2E, 0x22, 0x59, 0x74, 0x61, 0xA6, 0x5D, 0x73, 0x94, + 0xF8, 0xE4, 0xC1, 0x46, 0x26, 0x5E, 0x8A, 0x86, 0xED, 0xD4, 0xA6, 0x2D, 0x57, 0x6B, 0xBE, 0xE8, + 0x58, 0xDA, 0x3D, 0x98, 0x99, 0xBE, 0xA8, 0xC2, 0xDB, 0x6A, 0x2E, 0x51, 0x62, 0xE5, 0x80, 0x58, + 0x76, 0xB8, 0xE4, 0x6C, 0x84, 0xCA, 0x98, 0x06, 0x0B, 0xFC, 0xD2, 0x66, 0x7C, 0x62, 0x3A, 0x5B, + 0xC5, 0xDF, 0x7D, 0x75, 0x49, 0x1E, 0x52, 0xC7, 0x55, 0xF7, 0x84, 0xA6, 0xDA, 0x5D, 0x43, 0x26, + 0x85, 0x98, 0xD8, 0x8F, 0xB6, 0xC5, 0x28, 0xEB, 0x3E, 0x75, 0x04, 0xD2, 0x27, 0xBA, 0x2A, 0x2B, + 0xB7, 0x03, 0x13, 0x45, 0x35, 0x1B, 0x78, 0x5F, 0xC3, 0xBA, 0xDB, 0xAE, 0x27, 0xC2, 0x5E, 0xA4, + 0x50, 0x8C, 0x8A, 0xBB, 0x4F, 0x60, 0xC3, 0xEE, 0x41, 0x46, 0x4A, 0xDF, 0xD2, 0x27, 0xB2, 0xAD, + 0xEB, 0x5F, 0x43, 0x4C, 0x6A, 0x09, 0x2A, 0xCC, 0xB7, 0x47, 0x2A, 0xB9, 0x91, 0xB6, 0xD4, 0x5B, + 0x25, 0x58, 0xD8, 0xFD, 0x46, 0x95, 0x5A, 0xC3, 0x27, 0x5B, 0x3F, 0xFB, 0x12, 0xD2, 0x26, 0xC3, + 0xA9, 0xA1, 0xB6, 0xA2, 0xCB, 0x1B, 0xD0, 0x73, 0xE4, 0xBA, 0xA1, 0xE9, 0x05, 0xBE, 0x79, 0x23, + 0xA4, 0xC2, 0x3A, 0x4B, 0x11, 0xE5, 0x68, 0xC4, 0xC1, 0xBA, 0xC1, 0xCC, 0x8B, 0x02, 0xD2, 0x63, + 0x6C, 0xEE, 0x19, 0x5E, 0xE1, 0xB6, 0x4C, 0x1A, 0xB4, 0x5E, 0xF0, 0xC2, 0x27, 0x20, 0x55, 0xBD, + 0x6D, 0x64, 0xE1, 0xC7, 0x45, 0xA9, 0x65, 0x6D, 0x7D, 0x42, 0x56, 0xD8, 0xB2, 0xB6, 0xEC, 0xD3, + 0x61, 0x5B, 0x62, 0x61, 0x60, 0xA1, 0x5B, 0xD6, 0x15, 0x29, 0x09, 0x6C, 0xA1, 0x3E, 0xAD, 0x65, + 0x34, 0xC3, 0xC0, 0xC1, 0x22, 0x6D, 0x4C, 0x57, 0x10, 0xDB, 0x41, 0xD2, 0xE1, 0x77, 0x64, 0xF7, + 0xD3, 0x21, 0x73, 0xA9, 0x29, 0x58, 0xC1, 0xA1, 0x5A, 0x52, 0xB7, 0x32, 0x64, 0xC1, 0x67, 0x42, + 0x74, 0x2C, 0xDC, 0x61, 0x61, 0x65, 0x8B, 0xCB, 0x04, 0xE5, 0x60, 0xC1, 0xC9, 0x5E, 0x8E, 0x36, + 0x83, 0xD2, 0xA2, 0x83, 0xA9, 0xD9, 0xCD, 0x21, 0xB9, 0x25, 0xCD, 0xE6, 0x1D, 0x60, 0xA1, 0xB4, + 0xAA, 0x8F, 0xBA, 0x75, 0xC3, 0x01, 0x0B, 0x3B, 0x51, 0xDB, 0xEC, 0x62, 0xE1, 0x38, 0xCD, 0x40, + 0x3B, 0xD3, 0xD2, 0x26, 0x94, 0x29, 0xD2, 0x61, 0x21, 0x6B, 0x4A, 0x8D, 0x24, 0xB5, 0xBB, 0x21, + 0x12, 0xA5, 0x99, 0xA5, 0x1A, 0xCA, 0xA1, 0xEF, 0x5D, 0xAA, 0xAE, 0xD3, 0x64, 0xE1, 0xA3, 0x6B, + 0xAE, 0x35, 0x39, 0xD2, 0x66, 0x73, 0xB6, 0x90, 0xC6, 0xC1, 0x32, 0xD1, 0xBA, 0xC9, 0x25, 0x65, + 0x81, 0xA8, 0xD2, 0xB1, 0xE7, 0x18, 0xBE, 0xC0, 0xFC, 0xE4, 0x85, 0xB5, 0x06, 0xB4, 0x81, 0x35, + 0x46, 0xB6, 0xC8, 0x9B +}; + +#endif /* end of include guard: DATA_H */ diff --git a/all_pairs/source/gsm_enc/gsm_enc.c b/all_pairs/source/gsm_enc/gsm_enc.c new file mode 100644 index 0000000..cdac899 --- /dev/null +++ b/all_pairs/source/gsm_enc/gsm_enc.c @@ -0,0 +1,2072 @@ +/* gsm_enc_encode.c */ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +#include "../extra.h" +#include "private.h" + +/* + * Prototypes from add.c + */ + +extern word gsm_enc_div (word num, word denum); + +extern word gsm_enc_sub (word a, word b); + +extern word gsm_enc_norm ( longword a ); + +extern word gsm_enc_asl (word a, int n); + +extern word gsm_enc_asr (word a, int n); + +/* + * Inlined functions from add.h + */ + +#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) + +# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_L_ADD(a, b) \ + ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= (ulongword)MAX_LONGWORD \ + ? MAX_LONGWORD : a + b)) + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +#define saturate(x) \ + ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) + +/* Use these if necessary: + +# define GSM_MULT_R(a, b) gsm_enc_mult_r(a, b) +# define GSM_MULT(a, b) gsm_enc_mult(a, b) +# define GSM_L_MULT(a, b) gsm_enc_L_mult(a, b) + +# define GSM_L_ADD(a, b) gsm_enc_L_add(a, b) +# define GSM_ADD(a, b) gsm_enc_add(a, b) +# define GSM_SUB(a, b) gsm_enc_sub(a, b) + +# define GSM_ABS(a) gsm_enc_abs(a) +*/ + +/* + * More prototypes from implementations.. + */ +extern void gsm_enc_Gsm_Coder ( + struct gsm_state * S, + word * s, /* [0..159] samples IN */ + word * LARc, /* [0..7] LAR coefficients OUT */ + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */); + +extern void gsm_enc_Gsm_Long_Term_Predictor ( /* 4x for 160 samples */ + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + word * e, /* [0..40] OUT */ + word * dpp, /* [0..40] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */); + +extern void gsm_enc_Gsm_LPC_Analysis ( + word * s, /* 0..159 signals IN/OUT */ + word * LARc); /* 0..7 LARc's OUT */ + +extern void gsm_enc_Gsm_Preprocess ( + struct gsm_state * S, + word * s, word * so); + +extern void gsm_enc_Gsm_Short_Term_Analysis_Filter ( + struct gsm_state * S, + word * LARc, /* coded log area ratio [0..7] IN */ + word * d /* st res. signal [0..159] IN/OUT */); + +void gsm_enc_Gsm_RPE_Encoding ( + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc); /* [0..12] OUT */ + + +/**************** end #include "private.h" **********************************/ + +/* + * Interface + */ + +typedef struct gsm_state * gsm; +typedef short gsm_signal; /* signed 16 bit */ +typedef unsigned char gsm_byte; +typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ + +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +#define GSM_PATCHLEVEL 6 +#define GSM_MINOR 0 +#define GSM_MAJOR 1 + +#include "data.h" + +extern void gsm_enc_encode (gsm, gsm_signal *, gsm_byte *); + +extern int gsm_enc_explode (gsm, gsm_byte *, gsm_signal *); +extern void gsm_enc_implode (gsm, gsm_signal *, gsm_byte *); + + +/******************* end #include "gsm.h" **********************************/ + +#define SAMPLES 20 + +/* + Forward declaration of global variables +*/ + +struct gsm_state gsm_enc_state; +gsm gsm_enc_state_ptr; +volatile int gsm_enc_result; + + +/* add.c */ + +word gsm_enc_sub (word a, word b) +{ + longword diff = (longword)a - (longword)b; + return saturate(diff); +} + + +unsigned char gsm_enc_bitoff[ 256 ] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void gsm_enc_encode (gsm s, gsm_signal * source, gsm_byte * c) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + gsm_enc_Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); + + + /* variable size + + GSM_MAGIC 4 + + LARc[0] 6 + LARc[1] 6 + LARc[2] 5 + LARc[3] 5 + LARc[4] 4 + LARc[5] 4 + LARc[6] 3 + LARc[7] 3 + + Nc[0] 7 + bc[0] 2 + Mc[0] 2 + xmaxc[0] 6 + xmc[0] 3 + xmc[1] 3 + xmc[2] 3 + xmc[3] 3 + xmc[4] 3 + xmc[5] 3 + xmc[6] 3 + xmc[7] 3 + xmc[8] 3 + xmc[9] 3 + xmc[10] 3 + xmc[11] 3 + xmc[12] 3 + + Nc[1] 7 + bc[1] 2 + Mc[1] 2 + xmaxc[1] 6 + xmc[13] 3 + xmc[14] 3 + xmc[15] 3 + xmc[16] 3 + xmc[17] 3 + xmc[18] 3 + xmc[19] 3 + xmc[20] 3 + xmc[21] 3 + xmc[22] 3 + xmc[23] 3 + xmc[24] 3 + xmc[25] 3 + + Nc[2] 7 + bc[2] 2 + Mc[2] 2 + xmaxc[2] 6 + xmc[26] 3 + xmc[27] 3 + xmc[28] 3 + xmc[29] 3 + xmc[30] 3 + xmc[31] 3 + xmc[32] 3 + xmc[33] 3 + xmc[34] 3 + xmc[35] 3 + xmc[36] 3 + xmc[37] 3 + xmc[38] 3 + + Nc[3] 7 + bc[3] 2 + Mc[3] 2 + xmaxc[3] 6 + xmc[39] 3 + xmc[40] 3 + xmc[41] 3 + xmc[42] 3 + xmc[43] 3 + xmc[44] 3 + xmc[45] 3 + xmc[46] 3 + xmc[47] 3 + xmc[48] 3 + xmc[49] 3 + xmc[50] 3 + xmc[51] 3 + */ + + + *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF); + *c++ = ((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F); + *c++ = ((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7); + *c++ = ((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3); + *c++ = ((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7); + *c++ = ((Nc[0] & 0x7F) << 1) + | ((bc[0] >> 1) & 0x1); + *c++ = ((bc[0] & 0x1) << 7) + | ((Mc[0] & 0x3) << 5) + | ((xmaxc[0] >> 1) & 0x1F); + *c++ = ((xmaxc[0] & 0x1) << 7) + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1); + *c++ = ((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7); + *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3); + *c++ = ((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1); + *c++ = ((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7); + *c++ = ((Nc[1] & 0x7F) << 1) + | ((bc[1] >> 1) & 0x1); + *c++ = ((bc[1] & 0x1) << 7) + | ((Mc[1] & 0x3) << 5) + | ((xmaxc[1] >> 1) & 0x1F); + *c++ = ((xmaxc[1] & 0x1) << 7) + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1); + *c++ = ((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7); + *c++ = ((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3); + *c++ = ((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1); + *c++ = ((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7); + *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ + | ((bc[2] >> 1) & 0x1); + *c++ = ((bc[2] & 0x1) << 7) + | ((Mc[2] & 0x3) << 5) + | ((xmaxc[2] >> 1) & 0x1F); + *c++ = ((xmaxc[2] & 0x1) << 7) + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1); + *c++ = ((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7); + *c++ = ((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3); + *c++ = ((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1); + *c++ = ((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7); + *c++ = ((Nc[3] & 0x7F) << 1) + | ((bc[3] >> 1) & 0x1); + *c++ = ((bc[3] & 0x1) << 7) + | ((Mc[3] & 0x3) << 5) + | ((xmaxc[3] >> 1) & 0x1F); + *c++ = ((xmaxc[3] & 0x1) << 7) + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1); + *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7); + *c++ = ((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3); + *c++ = ((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1); + *c++ = ((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7); + +} + +/* decode.c */ +/* + * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER + */ + +/* code.c */ +void gsm_enc_Gsm_Coder ( + + struct gsm_state * S, + + word * s, /* [0..159] samples IN */ + +/* + * The RPE-LTD coder works on a frame by frame basis. The length of + * the frame is equal to 160 samples. Some computations are done + * once per frame to produce at the output of the coder the + * LARc[1..8] parameters which are the coded LAR coefficients and + * also to realize the inverse filtering operation for the entire + * frame (160 samples of signal d[0..159]). These parts produce at + * the output of the coder: + */ + + word * LARc, /* [0..7] LAR coefficients OUT */ + +/* + * Procedure 4.2.11 to 4.2.18 are to be executed four times per + * frame. That means once for each sub-segment RPE-LTP analysis of + * 40 samples. These parts produce at the output of the coder: + */ + + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */ +) +{ + int k; + word * dp = S->dp0 + 120; /* [ -120...-1 ] */ + word * dpp = dp; /* [ 0...39 ] */ + + static word e [50] = {0}; + + word so[160]; + + gsm_enc_Gsm_Preprocess (S, s, so); + gsm_enc_Gsm_LPC_Analysis (so, LARc); + gsm_enc_Gsm_Short_Term_Analysis_Filter (S, LARc, so); + + _Pragma("loopbound min 4 max 4") + for (k = 0; k <= 3; k++, xMc += 13) { + + gsm_enc_Gsm_Long_Term_Predictor ( + so+k*40, /* d [0..39] IN */ + dp, /* dp [-120..-1] IN */ + e + 5, /* e [0..39] OUT */ + dpp, /* dpp [0..39] OUT */ + Nc++, + bc++); + + gsm_enc_Gsm_RPE_Encoding ( + e + 5, /* e ][0..39][ IN/OUT */ + xmaxc++, Mc++, xMc ); + /* + * gsm_enc_Gsm_Update_of_reconstructed_short_time_residual_signal + * ( dpp, e + 5, dp ); + */ + + { int i; + longword ltmp; + _Pragma("loopbound min 40 max 40") + for (i = 0; i <= 39; i++) { + dp[ i ] = GSM_ADD( e[5 + i], dpp[i] ); + } + } + + dp += 40; + dpp += 40; + + } +// //(void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), +// // 120 * sizeof(*S->dp0) ); +} + +/* rpe.c */ +/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION + */ + +/* 4.2.13 */ + +void gsm_enc_Weighting_filter ( + word * e, /* signal [-5..0.39.44] IN */ + word * x /* signal [0..39] OUT */ +) +/* + * The coefficients of the weighting filter are stored in a table + * (see table 4.4). The following scaling is used: + * + * H[0..10] = integer( real_H[ 0..10] * 8192 ); + */ +{ + /* word wt[ 50 ]; */ + + longword L_result; + int k /* , i */ ; + + /* Initialization of a temporary working array wt[0...49] + */ + + /* for (k = 0; k <= 4; k++) wt[k] = 0; + * for (k = 5; k <= 44; k++) wt[k] = *e++; + * for (k = 45; k <= 49; k++) wt[k] = 0; + * + * (e[-5..-1] and e[40..44] are allocated by the caller, + * are initially zero and are not written anywhere.) + */ + e -= 5; + + /* Compute the signal x[0..39] + */ + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) { + + L_result = 8192 >> 1; + + /* for (i = 0; i <= 10; i++) { + * L_temp = GSM_L_MULT( wt[k+i], gsm_enc_H[i] ); + * L_result = GSM_L_ADD( L_result, L_temp ); + * } + */ + +#undef STEP +#define STEP( i, H ) (e[ k + i ] * (longword)H) + + /* Every one of these multiplications is done twice -- + * but I don't see an elegant way to optimize this. + * Do you? + */ + +#ifdef STUPID_COMPILER + L_result += STEP( 0, -134 ) ; + L_result += STEP( 1, -374 ) ; + /* + STEP( 2, 0 ) */ + L_result += STEP( 3, 2054 ) ; + L_result += STEP( 4, 5741 ) ; + L_result += STEP( 5, 8192 ) ; + L_result += STEP( 6, 5741 ) ; + L_result += STEP( 7, 2054 ) ; + /* + STEP( 8, 0 ) */ + L_result += STEP( 9, -374 ) ; + L_result += STEP( 10, -134 ) ; +#else + L_result += + STEP( 0, -134 ) + + STEP( 1, -374 ) + /* + STEP( 2, 0 ) */ + + STEP( 3, 2054 ) + + STEP( 4, 5741 ) + + STEP( 5, 8192 ) + + STEP( 6, 5741 ) + + STEP( 7, 2054 ) + /* + STEP( 8, 0 ) */ + + STEP( 9, -374 ) + + STEP(10, -134 ) + ; +#endif + /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) + * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) + * + * x[k] = SASR( L_result, 16 ); + */ + + /* 2 adds vs. >>16 => 14, minus one shift to compensate for + * those we lost when replacing L_MULT by '*'. + */ + + L_result = SASR( L_result, 13 ); + x[k] = ( L_result < MIN_WORD ? MIN_WORD + : (L_result > MAX_WORD ? MAX_WORD : L_result )); + } +} + +/* 4.2.14 */ + +void gsm_enc_RPE_grid_selection ( + word * x, /* [0..39] IN */ + word * xM, /* [0..12] OUT */ + word * Mc_out /* OUT */ +) +/* + * The signal x[0..39] is used to select the RPE grid which is + * represented by Mc. + */ +{ + /* word temp1; */ + int /* m, */ i; + longword L_result, L_temp; + longword EM; /* xxx should be L_EM? */ + word Mc; + + longword L_common_0_3; + + Mc = 0; + +#undef STEP +#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ + L_result += L_temp * L_temp; + + /* common part of 0 and 3 */ + + L_result = 0; + STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); + STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); + STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); + L_common_0_3 = L_result; + + /* i = 0 */ + + STEP( 0, 0 ); + L_result <<= 1; /* implicit in L_MULT */ + EM = L_result; + + /* i = 1 */ + + L_result = 0; + STEP( 1, 0 ); + STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); + STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); + STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 1; + EM = L_result; + } + + /* i = 2 */ + + L_result = 0; + STEP( 2, 0 ); + STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); + STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); + STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 2; + EM = L_result; + } + + /* i = 3 */ + + L_result = L_common_0_3; + STEP( 3, 12 ); + L_result <<= 1; + if (L_result > EM) { + Mc = 3; + } + + /**/ + + /* Down-sampling by a factor 3 to get the selected xM[0..12] + * RPE sequence. + */ + _Pragma("loopbound min 13 max 13") + for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; + *Mc_out = Mc; + +} + +/* 4.12.15 */ + +void gsm_enc_APCM_quantization_xmaxc_to_exp_mant ( + word xmaxc, /* IN */ + word * exp_out, /* OUT */ + word * mant_out ) /* OUT */ +{ + word exp, mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + exp = 0; + if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; + mant = xmaxc - (exp << 3); + + if (mant == 0) { + exp = -4; + mant = 7; + } + else { + _Pragma("loopbound min 0 max 3") + while (mant <= 7) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; + +} + +void gsm_enc_APCM_quantization ( + word * xM, /* [0..12] IN */ + + word * xMc, /* [0..12] OUT */ + word * mant_out, /* OUT */ + word * exp_out, /* OUT */ + word * xmaxc_out /* OUT */ +) +{ + int i, itest; + + word xmax, xmaxc, temp, temp1, temp2; + word exp, mant; + + + /* Find the maximum absolute value xmax of xM[0..12]. + */ + + xmax = 0; + + _Pragma("loopbound min 13 max 13") + for (i = 0; i <= 12; i++) { + temp = xM[i]; + temp = GSM_ABS(temp); + if (temp > xmax) xmax = temp; + } + + /* Qantizing and coding of xmax to get xmaxc. + */ + + exp = 0; + temp = SASR( xmax, 9 ); + itest = 0; + + _Pragma("loopbound min 6 max 6") + for (i = 0; i <= 5; i++) { + + itest |= (temp <= 0); + temp = SASR( temp, 1 ); + + if (itest == 0) exp++; // exp = add (exp, 1) + } + + temp = exp + 5; + + //xmaxc = gsm_enc_add( SASR(xmax, temp), exp << 3 ); + xmaxc = saturate( ( SASR(xmax, temp) + (exp << 3) )); + + /* Quantizing and coding of the xM[0..12] RPE sequence + * to get the xMc[0..12] + */ + + gsm_enc_APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); + + /* This computation uses the fact that the decoded version of xmaxc + * can be calculated by using the exponent and the mantissa part of + * xmaxc (logarithmic table). + * So, this method avoids any division and uses only a scaling + * of the RPE samples by a function of the exponent. A direct + * multiplication by the inverse of the mantissa (NRFAC[0..7] + * found in table 4.5) gives the 3 bit coded version xMc[0..12] + * of the RPE samples. + */ + + + /* Direct computation of xMc[0..12] using table 4.5 + */ + + + temp1 = 6 - exp; /* normalization by the exponent */ + temp2 = gsm_enc_NRFAC[ mant ]; /* inverse mantissa */ + + _Pragma("loopbound min 13 max 13") + for (i = 0; i <= 12; i++) { + + temp = xM[i] << temp1; + temp = GSM_MULT( temp, temp2 ); + temp = SASR(temp, 12); + xMc[i] = temp + 4; /* see note below */ + } + + /* NOTE: This equation is used to make all the xMc[i] positive. + */ + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; + +} + +/* 4.2.16 */ + +void gsm_enc_APCM_inverse_quantization ( + word * xMc, /* [0..12] IN */ + word mant, + word exp, + word * xMp) /* [0..12] OUT */ +/* + * This part is for decoding the RPE sequence of coded xMc[0..12] + * samples to obtain the xMp[0..12] array. Table 4.6 is used to get + * the mantissa of xmaxc (FAC[0..7]). + */ +{ + int i; + word temp, temp1, temp2, temp3; + longword ltmp; + + temp1 = gsm_enc_FAC[ mant ]; /* see 4.2-15 for mant */ + temp2 = gsm_enc_sub( 6, exp ); /* see 4.2-15 for exp */ + temp3 = gsm_enc_asl( 1, gsm_enc_sub( temp2, 1 )); + + _Pragma("loopbound min 13 max 13") + for (i = 13; i--;) { + + /* temp = gsm_enc_sub( *xMc++ << 1, 7 ); */ + temp = (*xMc++ << 1) - 7; /* restore sign */ + + temp <<= 12; /* 16 bit signed */ + temp = GSM_MULT_R( temp1, temp ); + temp = GSM_ADD( temp, temp3 ); + *xMp++ = gsm_enc_asr( temp, temp2 ); + } +} + +/* 4.2.17 */ + +void gsm_enc_RPE_grid_positioning ( + word Mc, /* grid position IN */ + word * xMp, /* [0..12] IN */ + word * ep /* [0..39] OUT */ +) +/* + * This procedure computes the reconstructed long term residual signal + * ep[0..39] for the LTP analysis filter. The inputs are the Mc + * which is the grid position selection and the xMp[0..12] decoded + * RPE samples which are upsampled by a factor of 3 by inserting zero + * values. + */ +{ + int i = 13; + + // + // TODO: rewritten Duff's device for WCET analysis! + // + switch (Mc) { + case 3: *ep++ = 0; + case 2: *ep++ = 0; + case 1: *ep++ = 0; + case 0: *ep++ = *xMp++; + i--; + } + + _Pragma("loopbound min 12 max 12") + do { + *ep++ = 0; + *ep++ = 0; + *ep++ = *xMp++; + } while (--i); + + _Pragma("loopbound min 0 max 3") + while (++Mc < 4) *ep++ = 0; + +} +/* +{ + int i = 13; + + // + //TODO: removed for WCET analysis +//_Pragma("marker outside") + switch (Mc) { + case 3: *ep++ = 0; + case 2: + _Pragma("loopbound min 13 max 13") + do { + *ep++ = 0; + case 1: *ep++ = 0; + case 0: + //_Pragma("marker inside") + *ep++ = *xMp++; + } while (--i); + } + + //_Pragma("flowrestriction 1*inside <= 13*outside") + + _Pragma("loopbound min 0 max 3") + while (++Mc < 4) *ep++ = 0; + +} +*/ + +/* 4.2.18 */ + +/* This procedure adds the reconstructed long term residual signal + * ep[0..39] to the estimated signal dpp[0..39] from the long term + * analysis filter to compute the reconstructed short term residual + * signal dp[-40..-1]; also the reconstructed short term residual + * array dp[-120..-41] is updated. + */ + +#if 0 /* Has been inlined in code.c */ +void gsm_enc_Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp) /* [-120...-1] IN/OUT */ +{ + int k; + + for (k = 0; k <= 79; k++) + dp[ -120 + k ] = dp[ -80 + k ]; + + for (k = 0; k <= 39; k++) + dp[ -40 + k ] = gsm_enc_add( ep[k], dpp[k] ); +} +#endif /* Has been inlined in code.c */ + +void gsm_enc_Gsm_RPE_Encoding ( + + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc) /* [0..12] OUT */ +{ + word x[40]; + word xM[13], xMp[13]; + word mant, exp; + + gsm_enc_Weighting_filter(e, x); + gsm_enc_RPE_grid_selection(x, xM, Mc); + + gsm_enc_APCM_quantization( xM, xMc, &mant, &exp, xmaxc); + gsm_enc_APCM_inverse_quantization( xMc, mant, exp, xMp); + + gsm_enc_RPE_grid_positioning( *Mc, xMp, e ); + +} + +/* long_term.c */ +#ifdef USE_TABLE_MUL + +unsigned int umul_table[ 513 ][ 256 ]; + +# define umul(x9, x15) \ + ((int)(umul_table[x9][x15 & 0x0FF] + (umul_table[x9][ x15 >> 8 ] << 8))) + +# define table_mul(a, b) \ + ( (a < 0) ? ((b < 0) ? umul(-a, -b) : -umul(-a, b)) \ + : ((b < 0) ? -umul(a, -b) : umul(a, b))) + +#endif /* USE_TABLE_MUL */ + + + +/* + * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION + */ + + +/* + * This procedure computes the LTP gain (bc) and the LTP lag (Nc) + * for the long term analysis filter. This is done by calculating a + * maximum of the cross-correlation function between the current + * sub-segment short term residual signal d[0..39] (output of + * the short term analysis filter; for simplification the index + * of this array begins at 0 and ends at 39 for each sub-segment of the + * RPE-LTP analysis) and the previous reconstructed short term + * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be + * performed to avoid overflow. + */ + + /* This procedure exists in four versions. First, the two integer + * versions with or without table-multiplication (as one function); + * then, the two floating point versions (as another function), with + * or without scaling. + */ + +#ifndef USE_FLOAT_MUL + +void gsm_enc_Calculation_of_the_LTP_parameters ( + word * d, /* [0..39] IN */ + word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_max, L_power; + word R, S, dmax, scal; + word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax != 0) + temp = gsm_enc_norm( (longword)dmax << 16 ); + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + + /* Initialization of a working array wt + */ + + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + _Pragma("loopbound min 81 max 81") + for (lambda = 40; lambda <= 120; lambda++) { + +# undef STEP +# ifdef USE_TABLE_MUL +# define STEP(k) (table_mul(wt[k], dp[k - lambda])) +# else +# define STEP(k) (wt[k] * dp[k - lambda]) +# endif + + longword L_result; + + L_result = STEP(0) ; L_result += STEP(1) ; + L_result += STEP(2) ; L_result += STEP(3) ; + L_result += STEP(4) ; L_result += STEP(5) ; + L_result += STEP(6) ; L_result += STEP(7) ; + L_result += STEP(8) ; L_result += STEP(9) ; + L_result += STEP(10) ; L_result += STEP(11) ; + L_result += STEP(12) ; L_result += STEP(13) ; + L_result += STEP(14) ; L_result += STEP(15) ; + L_result += STEP(16) ; L_result += STEP(17) ; + L_result += STEP(18) ; L_result += STEP(19) ; + L_result += STEP(20) ; L_result += STEP(21) ; + L_result += STEP(22) ; L_result += STEP(23) ; + L_result += STEP(24) ; L_result += STEP(25) ; + L_result += STEP(26) ; L_result += STEP(27) ; + L_result += STEP(28) ; L_result += STEP(29) ; + L_result += STEP(30) ; L_result += STEP(31) ; + L_result += STEP(32) ; L_result += STEP(33) ; + L_result += STEP(34) ; L_result += STEP(35) ; + L_result += STEP(36) ; L_result += STEP(37) ; + L_result += STEP(38) ; L_result += STEP(39) ; + + if (L_result > L_max) { + + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) { + + longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_enc_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + _Pragma("loopbound min 3 max 3") + for (bc = 0; bc <= 2; bc++) + /* Replaced by macro function. */ + //if (R <= gsm_enc_mult(S, gsm_enc_DLB[bc])) + if (R <= GSM_MULT(S, gsm_enc_DLB[bc])) + break; + + *bc_out = bc; +} + +#else /* USE_FLOAT_MUL */ + +void gsm_enc_Calculation_of_the_LTP_parameters ( + word * d, /* [0..39] IN */ + word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + temp = gsm_enc_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + float *lp = dp_float - lambda; + + float W; + float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + float E; + float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_enc_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + // Replaced by macro function. + //for (bc = 0; bc <= 2; bc++) if (R <= gsm_enc_mult(S, gsm_enc_DLB[bc])) break; + for (bc = 0; bc <= 2; bc++) if (R <= GSM_MULT(S, gsm_enc_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* USE_FLOAT_MUL */ + + +/* 4.2.12 */ + +void gsm_enc_Long_term_analysis_filtering ( + word bc, /* IN */ + word Nc, /* IN */ + word * dp, /* previous d [-120..-1] IN */ + word * d, /* d [0..39] IN */ + word * dpp, /* estimate [0..39] OUT */ + word * e /* long term res. signal [0..39] OUT */ +) +/* + * In this part, we have to decode the bc parameter to compute + * the samples of the estimate dpp[0..39]. The decoding of bc needs the + * use of table 4.3b. The long term residual signal e[0..39] + * is then calculated to be fed to the RPE encoding section. + */ +{ + int k; + longword ltmp; + +# undef STEP +# define STEP(BP) \ + _Pragma("loopbound min 40 max 40") \ + for (k = 0; k <= 39; k++) { \ + dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ + e[k] = GSM_SUB( d[k], dpp[k] ); \ + } + + switch (bc) { + case 0: STEP( 3277 ); break; + case 1: STEP( 11469 ); break; + case 2: STEP( 21299 ); break; + case 3: STEP( 32767 ); break; + } +} + +void gsm_enc_Gsm_Long_Term_Predictor ( + + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + + word * e, /* [0..39] OUT */ + word * dpp, /* [0..39] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */ +) +{ + + gsm_enc_Calculation_of_the_LTP_parameters( d, dp, bc, Nc ); + + gsm_enc_Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); +} + +/* short_term.c */ +/* + * SHORT TERM ANALYSIS FILTERING SECTION + */ + +/* 4.2.8 */ + +void gsm_enc_Decoding_of_the_coded_Log_Area_Ratios ( + word * LARc, /* coded log area ratio [0..7] IN */ + word * LARpp) /* out: decoded .. */ +{ + word temp1 /* , temp2 */; + long ltmp; /* for GSM_ADD */ + + /* This procedure requires for efficient implementation + * two tables. + * + * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) + * MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] + */ + +#undef STEP +#define STEP( B, MIC, INVA ) \ + temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ + temp1 = GSM_SUB( temp1, (B >= 0 ? B << 1 : -((-B) << 1))); \ + temp1 = GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = GSM_ADD( temp1, temp1 ); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( -2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( -1792, -8, 17476 ); + STEP( -341, -4, 31454 ); + STEP( -1144, -4, 29708 ); + + /* NOTE: the addition of *MIC is used to restore + * the sign of *LARc. + */ +} + +/* 4.2.9 */ +/* Computation of the quantized reflection coefficients + */ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] + */ + +/* + * Within each frame of 160 analyzed speech samples the short term + * analysis and synthesis filters operate with four different sets of + * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) + * and the actual set of decoded LARs (LARpp(j)) + * + * (Initial value: LARpp(j-1)[1..8] = 0.) + */ + +void gsm_enc_Coefficients_0_12 ( + word * LARpp_j_1, + word * LARpp_j, + word * LARp) +{ + int i; + longword ltmp; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); + } +} + +void gsm_enc_Coefficients_13_26 ( + word * LARpp_j_1, + word * LARpp_j, + word * LARp) +{ + int i; + longword ltmp; + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); + } +} + +void gsm_enc_Coefficients_27_39 ( + word * LARpp_j_1, + word * LARpp_j, + word * LARp) +{ + int i; + longword ltmp; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); + } +} + + +void gsm_enc_Coefficients_40_159 ( + word * LARpp_j, + word * LARp) +{ + int i; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARp++, LARpp_j++) { + *LARp = *LARpp_j; + } +} + +/* 4.2.9.2 */ + +void gsm_enc_LARp_to_rp ( + word * LARp) /* [0..7] IN/OUT */ +/* + * The input of this procedure is the interpolated LARp[0..7] array. + * The reflection coefficients, rp[i], are used in the analysis + * filter and in the synthesis filter. + */ +{ + int i; + word temp; + longword ltmp; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARp++) { + + /* temp = GSM_ABS( *LARp ); + * + * if (temp < 11059) temp <<= 1; + * else if (temp < 20070) temp += 11059; + * else temp = GSM_ADD( temp >> 2, 26112 ); + * + * *LARp = *LARp < 0 ? -temp : temp; + */ + + if (*LARp < 0) { + temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); + *LARp = - ((temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 ))); + } else { + temp = *LARp; + *LARp = (temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 )); + } + } +} + + +/* 4.2.10 */ +void gsm_enc_Short_term_analysis_filtering ( + struct gsm_state * S, + word * rp, /* [0..7] IN */ + int k_n, /* k_end - k_start */ + word * s /* [0..n-1] IN/OUT */ +) +/* + * This procedure computes the short term residual signal d[..] to be fed + * to the RPE-LTP loop from the s[..] signal and from the local rp[..] + * array (quantized reflection coefficients). As the call of this + * procedure can be done in many ways (see the interpolation of the LAR + * coefficient), it is assumed that the computation begins with index + * k_start (for arrays d[..] and s[..]) and stops with index k_end + * (k_start and k_end are defined in 4.2.9.1). This procedure also + * needs to keep the array u[0..7] in memory for each call. + */ +{ + word * u = S->u; + int i; + word di, zzz, ui, sav, rpi; + longword ltmp; + int j; + + _Pragma("loopbound min 13 max 120") + for (j=0; jLARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; + + word LARp[8]; + +#undef FILTER +# define FILTER gsm_enc_Short_term_analysis_filtering + + gsm_enc_Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); + + gsm_enc_Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s); + + gsm_enc_Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 14, s + 13); + + gsm_enc_Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s + 27); + + gsm_enc_Coefficients_40_159( LARpp_j, LARp); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 120, s + 40); +} + +/* lpc.c */ +#undef P + +/* + * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION + */ + +/* 4.2.4 */ + + +void gsm_enc_Autocorrelation ( + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +/* + * The goal is to compute the array L_ACF[k]. The signal s[i] must + * be scaled in order to avoid an overflow situation. + */ +{ + int k, i; + + word temp, smax, scalauto; + + /* Dynamic scaling of the array s[0..159] + */ + + /* Search for the maximum. + */ + smax = 0; + + _Pragma("loopbound min 160 max 160") + for (k = 0; k <= 159; k++) { + temp = GSM_ABS( s[k] ); + if (temp > smax) smax = temp; + } + + /* Computation of the scaling factor. + */ + if (smax == 0) scalauto = 0; + else { + scalauto = 4 - gsm_enc_norm( (longword)smax << 16 );/* sub(4,..) */ + } + + /* Scaling of the array s[0...159] + */ + + if (scalauto > 0) { + +# define SCALE(n) \ + case n: \ + _Pragma("loopbound min 160 max 160") \ + for (k = 0; k <= 159; k++) \ + s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ + break; + + switch (scalauto) { + SCALE(1) + SCALE(2) + SCALE(3) + SCALE(4) + } +# undef SCALE + } + + /* Compute the L_ACF[..]. + */ + { + word * sp = s; + word sl = *sp; +#undef STEP +# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); + +# define NEXTI sl = *++sp + + + _Pragma("loopbound min 9 max 9") + for (k = 9; k--; L_ACF[k] = 0) ; + + STEP (0); + NEXTI; + STEP(0); STEP(1); + NEXTI; + STEP(0); STEP(1); STEP(2); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); + + _Pragma("loopbound min 152 max 152") + for (i = 8; i <= 159; i++) { + + NEXTI; + + STEP(0); + STEP(1); STEP(2); STEP(3); STEP(4); + STEP(5); STEP(6); STEP(7); STEP(8); + } + + _Pragma("loopbound min 9 max 9") + for (k = 9; k--; L_ACF[k] <<= 1) ; + + } + /* Rescaling of the array s[0..159] + */ + if (scalauto > 0) { + _Pragma("loopbound min 160 max 160") + for (k = 160; k--; *s++ <<= scalauto) ; + } +} + +/* 4.2.5 */ + +void gsm_enc_Reflection_coefficients ( + longword * L_ACF, /* 0...8 IN */ + word * r /* 0...7 OUT */ +) +{ + int i, m, n; + word temp; + longword ltmp; + word ACF[9]; /* 0..8 */ + word P[ 9]; /* 0..8 */ + word K[ 9]; /* 2..8 */ + + /* Schur recursion with 16 bits arithmetic. + */ + + if (L_ACF[0] == 0) { + _Pragma("loopbound min 8 max 8") + for (i = 8; i--; *r++ = 0) ; + return; + } + + temp = gsm_enc_norm( L_ACF[0] ); + + /* ? overflow ? */ + _Pragma("loopbound min 9 max 9") + for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); + + /* Initialize array P[..] and K[..] for the recursion. + */ + + _Pragma("loopbound min 7 max 7") + for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; + + _Pragma("loopbound min 9 max 9") + for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; + + /* Compute reflection coefficients + */ + _Pragma("loopbound min 8 max 8") + for (n = 1; n <= 8; n++, r++) { + + temp = P[1]; + temp = GSM_ABS(temp); + if (P[0] < temp) { + _Pragma("loopbound min 8 max 8") + for (i = n; i <= 8; i++) *r++ = 0; + return; + } + + *r = gsm_enc_div( temp, P[0] ); + + if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ + if (n == 8) return; + + /* Schur recursion + */ + temp = GSM_MULT_R( P[1], *r ); + P[0] = GSM_ADD( P[0], temp ); + + _Pragma("loopbound min 1 max 7") + for (m = 1; m <= 8 - n; ++m) { + temp = GSM_MULT_R( K[ m ], *r ); + P[m] = GSM_ADD( P[ m+1 ], temp ); + + temp = GSM_MULT_R( P[ m+1 ], *r ); + K[m] = GSM_ADD( K[ m ], temp ); + } + } +} + +/* 4.2.6 */ + +void gsm_enc_Transformation_to_Log_Area_Ratios ( + word * r /* 0..7 IN/OUT */ +) +/* + * The following scaling for r[..] and LAR[..] has been used: + * + * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. + * LAR[..] = integer( real_LAR[..] * 16384 ); + * with -1.625 <= real_LAR <= 1.625 + */ +{ + word temp; + int i; + + + /* Computation of the LAR[0..7] from the r[0..7] + */ + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, r++) { + + temp = *r; + temp = GSM_ABS(temp); + + if (temp < 22118) { + temp >>= 1; + } else if (temp < 31130) { + temp -= 11059; + } else { + temp -= 26112; + temp <<= 2; + } + + *r = *r < 0 ? -temp : temp; + } +} + +/* 4.2.7 */ + +void gsm_enc_Quantization_and_coding ( + word * LAR /* [0..7] IN/OUT */ +) +{ + word temp; + longword ltmp; + + + /* This procedure needs four tables; the following equations + * give the optimum scaling for the constants: + * + * A[0..7] = integer( real_A[0..7] * 1024 ) + * B[0..7] = integer( real_B[0..7] * 512 ) + * MAC[0..7] = maximum of the LARc[0..7] + * MIC[0..7] = minimum of the LARc[0..7] + */ + +# undef STEP +# define STEP( A, B, MAC, MIC ) \ + temp = GSM_MULT( A, *LAR ); \ + temp = GSM_ADD( temp, B ); \ + temp = GSM_ADD( temp, 256 ); \ + temp = SASR( temp, 9 ); \ + *LAR = temp>MAC ? MAC - MIC : (tempz1; + longword L_z2 = S->L_z2; + word mp = S->mp; + + word s1; + longword L_s2; + + longword L_temp; + + word msp, lsp; + word SO; + + longword ltmp; /* for ADD */ + ulongword utmp; /* for L_ADD */ + + int k = 160; + + _Pragma("loopbound min 160 max 160") + while (k--) { + + /* 4.2.1 Downscaling of the input signal + */ + SO = SASR( *s, 3 ) << 2; + s++; + + /* 4.2.2 Offset compensation + * + * This part implements a high-pass filter and requires extended + * arithmetic precision for the recursive part of this filter. + * The input of this procedure is the array so[0...159] and the + * output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part + */ + + s1 = SO - z1; /* s1 = gsm_enc_sub( *so, z1 ); */ + z1 = SO; + + /* Compute the recursive part + */ + L_s2 = s1; + L_s2 <<= 15; + + /* Execution of a 31 bv 16 bits multiplication + */ + + msp = SASR( L_z2, 15 ); + lsp = L_z2-((longword)msp<<15); /* gsm_enc_L_sub(L_z2,(msp<<15)); */ + + L_s2 += GSM_MULT_R( lsp, 32735 ); + L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ + L_z2 = GSM_L_ADD( L_temp, L_s2 ); + + /* Compute sof[k] with rounding + */ + L_temp = GSM_L_ADD( L_z2, 16384 ); + + /* 4.2.3 Preemphasis + */ + + msp = GSM_MULT_R( mp, -28180 ); + mp = SASR( L_temp, 15 ); + *so++ = GSM_ADD( mp, msp ); + } + + S->z1 = z1; + S->L_z2 = L_z2; + S->mp = mp; +} + +/* gsm_enc_bench.c */ + +word gsm_enc_norm (longword a ) +/* + * the number of left shifts needed to normalize the 32 bit + * variable L_var1 for positive values on the interval + * + * with minimum of + * minimum of 1073741824 (01000000000000000000000000000000) and + * maximum of 2147483647 (01111111111111111111111111111111) + * + * + * and for negative values on the interval with + * minimum of -2147483648 (-10000000000000000000000000000000) and + * maximum of -1073741824 ( -1000000000000000000000000000000). + * + * in order to normalize the result, the following + * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); + * + * (That's 'ffs', only from the left, not the right..) + */ +{ + if (a < 0) { + if (a <= -1073741824) return 0; + a = ~a; + } + + return a & 0xffff0000 + ? ( a & 0xff000000 + ? -1 + gsm_enc_bitoff[ 0xFF & (a >> 24) ] + : 7 + gsm_enc_bitoff[ 0xFF & (a >> 16) ] ) + : ( a & 0xff00 + ? 15 + gsm_enc_bitoff[ 0xFF & (a >> 8) ] + : 23 + gsm_enc_bitoff[ 0xFF & a ] ); +} + +word gsm_enc_asl (word a, int n) +{ + if (n >= 16) return 0; + if (n <= -16) return -(a < 0); + if (n < 0) return gsm_enc_asr(a, -n); + return a << n; +} + +word gsm_enc_asr (word a, int n) +{ + if (n >= 16) return -(a < 0); + if (n <= -16) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(word)( -(uword)a >> n ); +# endif +} + +/* + * (From p. 46, end of section 4.2.5) + * + * NOTE: The following lines gives [sic] one correct implementation + * of the div(num, denum) arithmetic operation. Compute div + * which is the integer division of num by denum: with denum + * >= num > 0 + */ + +word gsm_enc_div ( word num, word denum) +{ + longword L_num = num; + longword L_denum = denum; + word div = 0; + int k = 15; + + /* The parameter num sometimes becomes zero. + * Although this is explicitly guarded against in 4.2.5, + * we assume that the result should then be zero as well. + */ + + if (num == 0) + return 0; + + _Pragma("loopbound min 15 max 15") + while (k--) { + div <<= 1; + L_num <<= 1; + + if (L_num >= L_denum) { + L_num -= L_denum; + div++; + } + } + + return div; +} + + + +gsm gsm_enc_create( void ) +{ + unsigned int i; + gsm r; + + r = &gsm_enc_state; + + _Pragma("loopbound min 648 max 648") + for(i=0; i < sizeof(*r); i++) + ((char *)r)[i]=0; + + r->nrp = 40; + + return r; +} + +void gsm_enc_init( void ) +{ + gsm_enc_state_ptr = gsm_enc_create(); +} + +int gsm_enc_return( void ) +{ + return gsm_enc_result; +} + +void gsm_enc_main( void ) +{ + gsm r; + unsigned i; + gsm_enc_result = 0; + + r = gsm_enc_state_ptr; + + _Pragma("loopbound min 20 max 20") + for (i=0; i < SAMPLES; i++) { + gsm_enc_encode(r, gsm_enc_pcmdata + i * 160, gsm_enc_gsmdata + i * sizeof(gsm_frame)); + } +} + +int main( int argc, char** argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete> (by)) + +/* Table 4.3a Decision level of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_enc_DLB[4] = { 6554, 16384, 26214, 32767 }; + + +/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_enc_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; + + +/* Table 4.6 Normalized direct mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_enc_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; +#endif /* PRIVATE_H */ diff --git a/all_pairs/source/h264_dec/changeLog.txt b/all_pairs/source/h264_dec/changeLog.txt new file mode 100644 index 0000000..2d5d97f --- /dev/null +++ b/all_pairs/source/h264_dec/changeLog.txt @@ -0,0 +1,41 @@ +File: h264dec_ldecode_macroblock.c +Original provenience: + +2015-12-21: +- Filename changed to h264dec.c +- global.h renamed to h264dec.h +- Removed commented out includes +- Removed all obsolete typedefs, enums and structs. Only remaining ones are + struct img_par and + enum SliceType +- Renamed function decode_one_macroblock to h264dec_decode_one_macroblock +- Function h264dec_decode_one_macroblock changed to void (i.e., removed statement return 0;) +- Added functions h264dec_init, h264dec_return and main +- Added forward declarations of all functions before the declarations of global + variables +- Struct 'ImageParameters' renamed to 'h264dec_ImageParameters' +- Re-ordered functions to fit template-order +- Applied code formatting according to the following rules + (incomplete, to be discussed; I basically used astyle with the attached + options file): + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: st_) followed by lowercase letter (e.g., st_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur +- Added general TACLeBench header to beginning of source code \ No newline at end of file diff --git a/all_pairs/source/h264_dec/copyright.txt b/all_pairs/source/h264_dec/copyright.txt new file mode 100644 index 0000000..fe3eece --- /dev/null +++ b/all_pairs/source/h264_dec/copyright.txt @@ -0,0 +1,32 @@ +/* +*********************************************************************** +* COPYRIGHT AND WARRANTY INFORMATION +* +* Copyright 2001, International Telecommunications Union, Geneva +* +* DISCLAIMER OF WARRANTY +* +* These software programs are available to the user without any +* license fee or royalty on an "as is" basis. The ITU disclaims +* any and all warranties, whether express, implied, or +* statutory, including any implied warranties of merchantability +* or of fitness for a particular purpose. In no event shall the +* contributor or the ITU be liable for any incidental, punitive, or +* consequential damages of any kind whatsoever arising from the +* use of these programs. +* +* This disclaimer of warranty extends to the user of these programs +* and user's customers, employees, agents, transferees, successors, +* and assigns. +* +* The ITU does not represent or warrant that the programs furnished +* hereunder are free of infringement of any third-party patents. +* Commercial implementations of ITU-T Recommendations, including +* shareware, may be subject to royalty fees to patent holders. +* Information regarding the ITU-T patent policy is available from +* the ITU Web site at http://www.itu.int. +* +* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY. +************************************************************************ +*/ + diff --git a/all_pairs/source/h264_dec/h264_dec.c b/all_pairs/source/h264_dec/h264_dec.c new file mode 100644 index 0000000..76af705 --- /dev/null +++ b/all_pairs/source/h264_dec/h264_dec.c @@ -0,0 +1,610 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: h264_dec_ldecode_macroblock.c + + Author: Inge Lille-Langoy et al. + + Function: H.264 decoder + + Source: MediaBench II + http://euler.slu.edu/~fritts/mediabench (mirror) + + Original name: h264_dec_ldecode_macroblock.c + + Changes: no functional changes + + License: see copyright.txt + +*/ + + +/* + Include section +*/ + +#include "../extra.h" +#include "h264_dec.h" + + +/* + Forward declaration of functions +*/ + +void h264_dec_init (); +int h264_dec_return (); +void h264_dec_decode_one_macroblock( struct h264_dec_img_par *img ); +void h264_dec_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +extern signed char h264_dec_mv_array[65][65][2]; +extern short h264_dec_list_imgUV[2][45][45]; +extern int h264_dec_img_m7[16][16]; + +char h264_dec_img_mpr[7][7]; +char h264_dec_dec_picture_imgUV[2][64][54]; +struct h264_dec_img_par h264_dec_img; + + +/* + Initialization- and return-value-related functions +*/ + +int h264_dec_return () +{ + return ( h264_dec_img_mpr[0][0] + h264_dec_dec_picture_imgUV[0][0][0] + 128 != + 0 ); +} + +void h264_dec_init () +{ + unsigned int i; + unsigned char *p; + volatile char bitmask = 0; + + /* + Apply volatile XOR-bitmask to entire input array. + */ + p = ( unsigned char * ) &h264_dec_mv_array[ 0 ]; + _Pragma( "loopbound min 33800 max 33800" ) + for ( i = 0; i < sizeof( h264_dec_mv_array ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &h264_dec_list_imgUV[ 0 ]; + _Pragma( "loopbound min 16200 max 16200" ) + for ( i = 0; i < sizeof( h264_dec_list_imgUV ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &h264_dec_img_m7[ 0 ]; + _Pragma( "loopbound min 1024 max 1024" ) + for ( i = 0; i < sizeof( h264_dec_img_m7 ); ++i, ++p ) + *p ^= bitmask; + + h264_dec_img.mb_cr_size_x = 8; + h264_dec_img.mb_cr_size_y = 8; + h264_dec_img.num_blk8x8_uv = 2; + h264_dec_img.pix_c_x = 256; + h264_dec_img.pix_c_y = 256; + h264_dec_img.width_cr = 352; + h264_dec_img.apply_weights = 0; + h264_dec_img.direct_spatial_mv_pred_flag = 1; + h264_dec_img.type = 1; + h264_dec_img.wp_round_chroma = 0; + h264_dec_img.chroma_log2_weight_denom = 0; +} + + +/* + Algorithm core functions +*/ + +void h264_dec_decode_one_macroblock( struct h264_dec_img_par *img ) +{ + int i = 0, j = 0, ii = 0, jj = 0, i1 = 0, j1 = 0, j4 = 0, i4 = 0; + int uv; + int ioff, joff; + int bw_pred = 0, fw_pred = 0, ifx; + int ii0, jj0, ii1, jj1, if1, jf1, if0, jf0; + int f1_x, f1_y, f2_x, f2_y, f3, f4; + + short fw_refframe = -1, bw_refframe = -1; + int mv_mode, pred_dir, intra_prediction; // = currMB->ref_frame; + short fw_ref_idx = -1, bw_ref_idx = -1; + + int mb_nr = 0; + short dec_picture_ref_idx = 0; + + short active_sps_chroma_format_idc = 1; + short active_pps_weighted_pred_flag = 0; + short active_pps_weighted_bipred_idc = 0; + + int smb = 0; + int max_y_cr = 287; + + int jf; + + int direct_pdir = -1; + + int curr_mb_field = 0; + + int b8, b4; + + int residue_transform_flag = 0; + + if ( 1 ) { + f1_x = 64 / img->mb_cr_size_x; + f2_x = f1_x - 1; + + f1_y = 64 / img->mb_cr_size_y; + f2_y = f1_y - 1; + + f3 = f1_x * f1_y; + f4 = f3 >> 1; + + _Pragma( "loopbound min 2 max 2" ) + for ( uv = 0; uv < 2; uv++ ) { + intra_prediction = 0; + + + _Pragma( "loopbound min 1 max 1" ) + for ( b8 = 0; b8 < ( img->num_blk8x8_uv / 2 ); b8++ ) { + _Pragma( "loopbound min 4 max 4" ) + for ( b4 = 0; b4 < 4; b4++ ) { + joff = 0; + j4 = img->pix_c_y + joff; + ioff = 0; + i4 = img->pix_c_x + ioff; + + mv_mode = 1; + pred_dir = -1; + + if ( !intra_prediction ) { + if ( pred_dir != 2 ) { + + _Pragma( "loopbound min 4 max 4" ) + for ( jj = 0; jj < 4; jj++ ) { + jf = ( ( j4 + jj ) / ( img->mb_cr_size_y / 4 ) ) % 64; + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) { + ifx = ( ( i4 + ii ) / ( img->mb_cr_size_x / 4 ) ) % 64; + i1 = ( i4 + ii ) * f1_x + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) + j1 = ( j4 + jj ) * f1_y + h264_dec_mv_array[jf][ifx][1]; + else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y / 2 ) + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + ++mb_nr; + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( + ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : ( i1 + f2_x ) / f1_x ) ) + ? ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) + ? max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) ) % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + if ( img->apply_weights ) { + } else { + h264_dec_img_mpr[ii + ioff][jj + joff] + = ( if0 * jf0 * h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + } + } + } else { + + _Pragma( "loopbound min 4 max 4" ) + for ( jj = 0; jj < 4; jj++ ) { + jf = ( j4 + jj ) / ( img->mb_cr_size_y / 4 ); + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) { + ifx = ( i4 + ii ) / ( img->mb_cr_size_x / 4 ); + direct_pdir = 2; + + if ( mv_mode == 0 && img->direct_spatial_mv_pred_flag ) { + if ( dec_picture_ref_idx != -1 ) { + fw_refframe = 0; + fw_ref_idx = fw_refframe; + } + if ( dec_picture_ref_idx != -1 ) { + bw_refframe = 0; + bw_ref_idx = bw_refframe; + } + + if ( dec_picture_ref_idx == -1 ) direct_pdir = 0; + else + if ( dec_picture_ref_idx == -1 ) direct_pdir = 1; + + if ( direct_pdir == 0 || direct_pdir == 2 ) { + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * + f1_y + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) + / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( + ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( + ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? ( ( + j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) + ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) + ) % 45; + + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + fw_pred = ( if0 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + if ( direct_pdir == 1 || direct_pdir == 2 ) { + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) ) + % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + bw_pred = ( if0 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + + } else { + fw_refframe = 0; + bw_refframe = 0; + + fw_ref_idx = fw_refframe; + bw_ref_idx = bw_refframe; + + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) + % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : + ( j1 + f2_y ) / f1_y ) : 0 ) ) % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + fw_pred = ( if0 * jf0 * h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + jj + + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) ) % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + bw_pred = ( if0 * jf0 * h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + + if ( img->apply_weights ) { + if ( ( ( active_pps_weighted_pred_flag && + ( img->type == P_SLICE || img->type == SP_SLICE ) ) + || ( active_pps_weighted_bipred_idc == 1 && + ( img->type == B_SLICE ) ) ) + && curr_mb_field ) { + fw_ref_idx >>= 1; + bw_ref_idx >>= 1; + } + + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 1 ) { + img->mpr[ii + ioff][jj + joff] = + ( ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) < 0 ? 0 : + ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) ) + 0; + } else + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 0 ) { + img->mpr[ii + ioff][jj + joff] = + ( ( ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) ) < 0 ? + 0 : + ( ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) ) ) ; + } else { + + int alpha_fw = 0; + int alpha_bw = 0; + + img->mpr[ii + ioff][jj + joff] = + ( ( ( alpha_fw * fw_pred + alpha_bw * + bw_pred + + ( 1 << img->chroma_log2_weight_denom ) ) >> ( + img->chroma_log2_weight_denom + 1 ) ) < 0 ? + 0 : ( ( alpha_fw * fw_pred + alpha_bw * + bw_pred + + ( 1 << img->chroma_log2_weight_denom ) ) >> + ( img->chroma_log2_weight_denom + 1 ) ) ); + } + } else { + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 1 ) + img->mpr[ii + ioff][jj + joff] = bw_pred; + else + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 0 ) + img->mpr[ii + ioff][jj + joff] = fw_pred; + else { + img->mpr[ii + ioff][jj + joff] = ( fw_pred + bw_pred + + + 1 ) / 2; + } + } + } + } + } + } + + if ( !smb ) { + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) { + jj = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; jj < 4; jj++ ) { + if ( !residue_transform_flag ) { + h264_dec_dec_picture_imgUV[uv][( j4 + jj ) % 64] + [( i4 + ii ) % 54] + = h264_dec_img_m7[ii][jj]; + } + } + } + } + } + } + + if ( smb ) { + _Pragma( "loopbound min 2 max 2" ) + for ( j = 4; j < 6; j++ ) { + joff = ( j - 4 ) * 4; + j4 = img->pix_c_y + joff; + _Pragma( "loopbound min 2 max 2" ) + for ( i = 0; i < 2; i++ ) { + ioff = i * 4; + i4 = img->pix_c_x + ioff; + + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) + _Pragma( "loopbound min 4 max 4" ) + for ( jj = 0; jj < 4; jj++ ) { + h264_dec_dec_picture_imgUV[uv][( j4 + jj ) % 64] + [( i4 + ii ) % 54] + = h264_dec_img_m7[ii][jj]; + } + } + } + } + } + } +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) h264_dec_main( void ) +{ + h264_dec_decode_one_macroblock( &h264_dec_img ); +} + + +int main( int argc, char** argv ) +{ + SET_UP + for (jobsComplete=-1; jobsCompletesource_memory_end) +#define read_byte() (*(source_ptr++)) + +If you want to compress *to* memory, before entering in a xxxcoding procedure +('xxx' is the actual extension to replace with a given codec), you have to add +a pointer. Note that the pointer 'dest_memory_base' is not to add, it is just +given there to specify the address of the destination memory zone you are +going to encode or decode. + +unsigned char *dest_memory_base, /* Base of the destination memory */ + *dest_ptr; /* Used in the xxxcoding procedure */ +void pre_start() +{ dest_ptr=dest_memory_base; + xxxcoding(); +} + +Of course, you can combine both from and to memory in the pre_start() procedure. +The files dest_file and source_file handled in the main() function are +to remove... + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + xxxcoding(); +} + +In fact, to write to memory, the problem is in the write_byte(x) procedure. +This problem exists because your destination zone can either be a static +zone or a dynamically allocated zone. In the two cases, you have to check +if there is no overflow, especially if the coder is not efficient and must +produce more bytes than you reserved in memory. + +In the first case, with a *static* zone, write_byte(x) macro should look like +that: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + exit(1); \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +In the static version, the pre_start() procedure is to modify as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=...; /* Set up to the actual destination zone length */ + current_size=0; /* Number of written bytes */ + xxxcoding(); +} +Otherwise, dest_ptr is a zone created by the malloc instruction and you can try +to resize the allocated zone with the realloc instruction. Note that I increment +the zone one kilo-bytes by one kylo-bytes. You have to add two other variables: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + { dest_zone_length += 1024; \ + if ((dest_ptr=(unsigned char *)realloc(dest_ptr,dest_zone_length*sizeof(unsigned char)))==NULL) \ + exit(1); /* You can't compress in memory \ + => I exit but *you* can make a routine to swap on disk */ \ + } \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +With the dynamically allocated version, change the pre_start() routine as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=1024; + if ((dest_ptr=(unsigned char *)malloc(dest_zone_length*sizeof(unsigned char)))==NULL) + exit(1); /* You need at least 1 kb in the dynamical memory ! */ + current_size=0; /* Number of written bytes */ + xxxcoding(); + /* Handle the bytes in dest_ptr but don't forget to free these bytes with: + free(dest_ptr); + */ +} + +The previously given macros work as: + +void demo() /* The file opening, closing and variables + must be set up by the calling procedure */ +{ unsigned char byte; + /* And not 'char byte' (!) */ + while (!end_of_data()) + { byte=read_byte(); + printf("Byte read=%c\n",byte); + } +} + +You must not change the rest of the program unless you're really sure and +really need to do it! + ++==========================================================+ +| The RLE encoding | ++==========================================================+ + +RLE is an acronym that stands for Run Length Encoding. You may encounter it +as an other acronym: RLC, Run Length Coding. + +The idea in this scheme is to recode your data with regard to the repetition +frames. A frame is one or more bytes that occurr one or several times. + +There are several means to encode occurrences. So, you'll have several codecs. +For example, you may have a sequence such as: +0,0,0,0,0,0,255,255,255,2,3,4,2,3,4,5,8,11 + +Some codecs will only deal with the repetitions of '0' and '255' but some other +will deal with the repetitions of '0', '255', and '2,3,4'. + +You have to keep in your mind something important based on this example. A codec +won't work on all the data you will try to compress. So, in case of non +existence of sequence repetitions, the codecs based on RLE schemes must not +display a message to say: "Bye bye". Actually, they will try to encode these +non repeted data with a value that says "Sorry, I only make a copy of the inital +input". Of course, a copy of the input data with an header in front of this copy +will make a biggest output data but if you consider the whole data to compress, +the encoding of repeated frames will take less space than the encoding +of non-repeated frames. + +All of the algorithms with the name of RLE have the following look with three +or four values: +- Value saying if there's a repetition +- Value saying how many repetitions (or non repetition) +- Value of the length of the frame (useless if you just encode frame +with one byte as maximum length) +- Value of the frame to repeat (or not) + +I gave four algorithms to explain what I say. + +*** First RLE scheme *** + +The first scheme is the simpliest I know, and looks like the one used in MAC +system (MacPackBit) and some image file formats such as Targa, PCX, TIFF, ... + +Here, all compressed blocks begin with a byte, named header, which description +is: + +Bits 7 6 5 4 3 2 1 0 +Header X X X X X X X X + +Bits 7: Compression status (1=Compression applied) + 0 to 6: Number of bytes to handle + +So, if the bit 7 is set up to 0, the 0 to 6 bits give the number of bytes +that follow (minus 1, to gain more over compress) and that were not compressed +(native bytes). If the bit 7 is set up to 1, the same 0 to 6 bits give +the number of repetition (minus 2) of the following byte. + +As you see, this method only handle frame with one byte. + +Additional note: You have 'minus 1' for non-repeated frames because you must +have at least one byte to compress and 'minus 2' for repeated frames because the +repetition must be 2, at least. + +Compression scheme: + + First byte=Next + /\ + / \ +Count the byte Count the occurrence of NON identical +occurrences bytes (maximum 128 times) +(maximum 129 times) and store them in an array + | | + | | + 1 bit '1' 1 bit '0' ++ 7 bits giving + 7 bits giving + the number (-2) the number (-1) + of repetitions of non repetition ++ repeated byte + n non repeated bytes + | | + 1xxxxxxx,yyyyyyyy 0xxxxxxx,n bytes +[-----------------] [----------------] + +Example: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 1,255,15, | -1 + 255,255, | 128,255, | 0 + 15,15, | 128,15, | 0 + 255,255,255, | 129,255, | +1 + 15,15,15, | 129,15, | +1 + 255,255,255,255, | 130,255, | +2 + 15,15,15,15 | 130,15 | +2 + +See codecs source codes: codrle1.c and dcodrle1.c + +*** Second RLE scheme *** + +In the second scheme of RLE compression you look for the less frequent byte +in the source to compress and use it as an header for all compressed block. + +In the best cases, the occurrence of this byte is zero in the data to compress. + +Two possible schemes, firstly with handling frames with only one byte, +secondly with handling frames with one byte *and* more. The first case is +the subject of this current compression scheme, the second is the subject +of next compression scheme. + +For the frame of one byte, header byte is written in front of all repetition +with at least 4 bytes. It is then followed by the repetition number minus 1 and +the repeated byte. +Header byte, Occurrence number-1, repeated byte + +If a byte don't repeat more than tree times, the three bytes are written without +changes in the destination stream (no header nor length, nor repetition in front +or after theses bytes). + +An exception: If the header byte appears in the source one, two, three and up +times, it'll be respectively encoded as following: +- Header byte, 0 +- Header byte, 1 +- Header byte, 2 +- Header byte, Occurrence number-1, Header byte + +Example, let's take the previous example. A non frequent byte is zero-ASCII +because it never appears. + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 255,15, | -1 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 0,3,255, | -1 + 15,15,15,15 | 0,3,15 | -1 + +If the header would appear, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 0, | 0,0, | +1 + 255, | 255, | 0 + 0,0, | 0,1, | 0 + 15, | 15, | 0 + 0,0,0, | 0,2, | -1 + 255, | 255, | 0 + 0,0,0,0 | 0,3,0 | -1 + +See codecs source codes: codrle2.c and dcodrle2.c + +*** Third RLE scheme *** + +It's the same idea as the second scheme but we can encode frames with +more than one byte. So we have three cases: + +- If it was the header byte, whatever is its occurrence, you encode it with: +Header byte,0,number of occurrence-1 +- For frames which (repetition-1)*length>3, encode it as: +Header byte, Number of frame repetition-1, frame length-1,bytes of frame +- If no previous cases were detected, you write them as originally (no header, +nor length, nor repetition in front or after theses bytes). + +Example based on the previous examples: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +----------------------------------------------------------------------------- + 255,15, | 255,15, | 0 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 255,255,255,255, | 0 + 15,15,15,15, | 15,15,15,15, | 0 + 16,17,18,16,17,18, |16,17,18,16,17,18,| 0 + 255,255,255,255,255, | 0,4,0,255, | -1 + 15,15,15,15,15, | 0,4,0,15, | -1 + 16,17,18,16,17,18,16,17,18,| 0,2,2,16,17,18, | -3 + 16,17,18,19,16,17,18,19 |0,1,3,16,17,18,19 | -1 + +If the header (value 0) would be met, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 0, | 0,0,0, | +2 + 255, | 255, | 0 + 0,0, | 0,0,1, | +1 + 15, | 15, | 0 + 0,0,0, | 0,0,2, | 0 + 255, | 255, | 0 + 0,0,0,0 | 0,0,3 | -1 + +See codecs source codes: codrle3.c and dcodrle3.c + +*** Fourth RLE scheme *** + +This last RLE algorithm better handles repetitions of any kind (one byte +and more) and non repetitions, including few non repetitions, and does not +read the source by twice as RLE type 3. + +Compression scheme is: + + First byte=Next byte? + /\ + Yes / \ No + / \ + 1 bit '0' 1 bit '1' + / \ + / \ + Count the Motif of several + occurrences repeated byte? + of 1 repeated ( 65 bytes repeated + byte (maximum 257 times maxi) + 16449 times) /\ + /\ / \ + / \ / \ + / \ / \ + / \ / \ + 1 bit '0' 1 bit '1' 1 bit '0' 1 bit '1' ++ 6 bits + 14 bits + 6 bits of | +giving the giving the the length Number of non repetition +length (-2) length (-66) of the motif (maximum 8224) +of the of the + 8 bits of /\ +repeated byte repeated byte the number (-2) < 33 / \ > 32 ++ repeated byte + repeated byte of repetition / \ + | | + bytes of the 1 bit '0' 1 bit '1' + | | motif + 5 bits of + 13 bits + | | | the numer (-1) of the + | | | of non number (-33) + | | | repetition of repetition + | | | + non + non + | | | repeated repeated + | | | bytes bytes + | | | | | + | | | | 111xxxxx,xxxxxxxx,n bytes + | | | | [-------------------------] + | | | | + | | | 110xxxxx,n bytes + | | | [----------------] + | | | + | | 10xxxxxx,yyyyyyyy,n bytes + | | [-------------------------] + | | + | 01xxxxxx,xxxxxxxx,1 byte + | [------------------------] + | + 00xxxxxx,1 byte +[---------------] + +Example, same as previously: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 255,15 | 11000001b,255,15, | +1 + 255,255 | 00000000b,255, | 0 + 15,15 | 00000000b,15, | 0 + 255,255,255 | 00000001b,255, | -1 + 15,15,15 | 00000001b,15, | -1 + 255,255,255,255 | 00000010b,255, | -2 + 15,15,15,15 | 00000010b,15, | -2 + 16,17,18,16,17,18 |10000001b,0,16,17,18,| -1 + 255,255,255,255,255 | 00000011b,255, | -3 + 15,15,15,15,15 | 00000011b,15, | -3 + 16,17,18,16,17,18,16,17,18 | 10000001b,16,17,18, | -4 + 16,17,18,19,16,17,18,19 |10000010b,16,17,18,19| -2 + ++==========================================================+ +| The Huffman encoding | ++==========================================================+ + +This method comes from the searcher who established the algorithm in 1952. +This method allows both a dynamic and static statistic schemes. A statistic +scheme works on the data occurrences. It is not as with RLE where you had +a consideration of the current occurrence of a frame but rather a consideration +of the global occurrences of each data in the input stream. In this last case, +frames can be any kinds of sequences you want. On the other hand, Huffman +static encoding appears in some compressers such as ARJ on PCs. This enforces +the encoder to consider every statistic as the same for all the data you have. +Of course, the results are not as good as if it were a dynamic encoding. +The static encoding is faster than the dynamic encoding but the dynamic encoding +will be adapted to the statistic of the bytes of the input stream and will +of course become more efficient by producing shortest output. + +The main idea in Huffman encoding is to re-code every byte with regard to its +occurrence. The more frequent bytes in the data to compress will be encoded with +less than 8 bits and the others could need 8 bits see even more to be encoded. +You immediately see that the codes associated to the different bytes won't have +identical size. The Huffman method will actually require that the binary codes +have not a fixed size. We speak then about variable length codes. + +The dynamical Huffman scheme needs the binary trees for the encoding. This +enables you to obtain the best codes, adapted to the source data. +The demonstration won't be given there. To help the neophyt, I will just explain +what is a binary tree. + +A binary tree is special fashion to represent the data. A binary tree is +a structure with an associated value with two pointers. The term of binary has +been given because of the presence of two pointers. Because of some conventions, +one of the pointer is called left pointer and the second pointer is called right +pointer. Here is a visual representation of a binary tree. + + Value + / \ + / \ + Value Value + / \ / \ +... ... ... ... + +One problem with a binary encoding is a prefix problem. A prefix is the first +part of the representation of a value, e.g. "h" and "he" are prefixes of "hello" +but not "el". To understand the problem, let's code the letters "A", "B", "C", +"D", and "E" respectively as 00b, 01b, 10b, 11b, and 100b. When you read +the binary sequence 00100100b, you are unable to say if this comes from "ACBA" +or "AEE". To avoid such situations, the codes must have a prefix property. +And the letter "E" mustn't begin with the sequence of an other code. With "A", +"B", "C", "D", and "E" respectively affected with 1b, 01b, 001b, 0001b, and +0000b, the sequence 1001011b will only be decoded as "ACBA". + + 1 0 +<- /\ -> + / \ + "A" /\ + "B" \ + /\ + "C" \ + /\ + "D" "E" + +As you see, with this tree, an encoding will have the prefix property +if the bytes are at the end of each "branch" and you have no byte at the "node". +You also see that if you try to reach a character by the right pointer you add +a bit set to 0 and by the left pointer, you add a bit set to 1 to the current +code. The previous *bad* encoding provide the following bad tree: + + /\ + / \ + / \ + /\ /\ + / \ "B" "A" + / \ +"D" "C"\ + / \ + "E" + +You see here that the coder shouldn't put the "C" at a node... + +As you see, the largest binary code are those with the longest distance +from the top of the tree. Finally, the more frequent bytes will be the highest +in the tree in order you have the shortest encoding and the less frequent bytes +will be the lowest in the tree. + +From an algorithmic point of view, you make a list of each byte you encountered +in the stream to compress. This list will always be sorted. The zero-occurrence +bytes are removed from this list. You take the two bytes with the smallest +occurrences in the list. Whenever two bytes have the same "weight", you take two +of them regardless to their ASCII value. You join them in a node. This node will +have a fictive byte value (256 will be a good one!) and its weight will be +the sum of the two joined bytes. You replace then the two joined bytes with +the fictive byte. And you continue so until you have one byte (fictive or not) +in the list. Of course, this process will produce the shortest codes if the list +remains sorted. I will not explain with arcana hard maths why the result +is a set of the shortest bytes... + +Important: I use as convention that the right sub-trees have a weight greater +or equal to the weight of the left sub-trees. + +Example: Let's take a file to compress where we notice the following +occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +We will begin by joining the bytes 83 and 222. This will produce a fictive node +1 with a weight of 20+5=25. + +(Fictive 1,25) + /\ + / \ +(222,5) (83,20) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 1 | 25 + 77 | 24 + 115 | 21 + +Note that the list is sorted... The smallest values in the frequences are 21 and +24. That is why we will take the bytes 77 and 115 to build the fictive node 2. + +(Fictive 2,45) + /\ + / \ +(115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 2 | 45 + Fictive 1 | 25 + +The nodes with smallest weights are the fictive 1 and 2 nodes. These are joined +to build the fictive node 3 whose weight is 40+25=70. + + (Fictive 3,70) + / \ + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 3 | 70 + +The fictive node 3 is linked to the byte 31. Total weight: 280+70=350. + + (Fictive 4,350) + / \ + / \ + / \ + / \ (31,280) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 4 | 350 + 0 | 338 + 255 | 300 + +As you see, being that we sort the list, the fictive node 4 has become the first +of the list. We join the bytes 0 and 255 in a same fictive node, the number 5 +whose weight is 338+300=638. + +(Fictive 5,638) + /\ + / \ +(255,300) (0,338) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 5 | 638 + Fictive 4 | 350 + +The fictive nodes 4 and 5 are finally joined. Final weight: 638+350=998 bytes. +It is actually the total byte number in the initial file: 338+300+24+21+20+5. + + (Tree,998) + 1 / \ 0 + <- / \ -> + / \ + / \ + / \ + / \ / \ + / \ / \ + / \ / \ + / \ (31,280) (255,300) (0,338) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Bytes | Huffman codes | Frequences | Binary length*Frequence +------------------------------------------------------------ + 0 | 00b | 338 | 676 + 255 | 01b | 300 | 600 + 31 | 10b | 280 | 560 + 77 | 1101b | 24 | 96 + 115 | 1100b | 21 | 84 + 83 | 1110b | 20 | 80 + 222 | 1111b | 5 | 20 + +Results: Original file size: (338+300+280+24+21+20+5)*8=7904 bits (=998 bytes) +versus 676+600+560+96+84+80+20=2116 bits, i.e. 2116/8=265 bytes. + +Now you know how to code an input stream. The last problem is to decode all this +stuff. Actually, when you meet a binary sequence you can't say whether it comes +from such byte list or such other one. Furthermore, if you change the occurrence +of one or two bytes, you won't obtain the same resulting binary tree. Try for +example to encode the previous list but with the following occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 255 | 418 + 0 | 300 + 31 | 100 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +As you can observe it, the resulting binary tree is quite different, we had yet +the same initial bytes. To not be in such a situation we will put an header +in front of all data. I can't comment longly this header but I can say +I minimize it as much as I could. The header is divided into two parts. +The first part of this header looks closely to a boolean table (coded more or +less in binary to save space) and the second part provide to the decoder +the binary code associated to each byte encountered in the original input +stream. + +Here is a summary of the header: + +First part +---------- + First bit + / \ + 1 / \ 0 + / \ + 256 bits set to 0 or 1 5 bits for the number n (minus 1) + depending whether the of bytes encountered + corresponding byte was in the file to compres + in the file to compress | + (=> n bits set to 1, \ / + n>32) n values of 8-bits (n<=32) + \ / + \ / + \ / +Second part | +----------- | + | + +------------->| +(n+1) times | | +(n bytes of | First bit? +the values | / \ +encountered | 1 / \ 0 +in the | / \ +source file | 8 bits of 5 bits of the ++ the code | the length length (-1) +of a | (-1) of the of the following +fictive | following binary +byte | binary code code +to stop the | (length>32) (length<=32) +decoding. | \ / +The fictive | \ / +is set to | \ / +256 in the | | +Huffman | binary code +-tree of | | +encoding) +--------------| + | + Binary encoding of the source file + | + Code of end of encoding + | + + +With my codecs I can handle binary sequences with a length of 256 bits. +This correspond to encode all the input stream from one byte to infinite length. +In fact if a byte had a range from 0 to 257 instead of 0 to 255, I would have a +bug with my codecs with an input stream of at least 370,959,230,771,131,880,927, +453,318,055,001,997,489,772,178,180,790,105 bytes !!! + +Where come this explosive number? In fact, to have a severe bug, I must have +a completely unbalanced tree: + + Tree + /\ + \ + /\ + \ + /\ + \ + ... + /\ + \ + /\ + +Let's take the following example: + +Listed bytes | Frequences (Weight) +---------------------------------- + 32 | 5 + 101 | 3 + 97 | 2 + 100 | 1 + 115 | 1 + +This produces the following unbalanced tree: + + Tree + /\ +(32,5) \ + /\ + (101,3) \ + /\ + (97,2) \ + /\ + (115,1) (100,1) + +Let's speak about a mathematical series: The Fibonacci series. It is defined as +following: + +{ Fib(0)=0 +{ Fib(1)=1 +{ Fib(n)=Fib(n-2)+Fib(n-1) + +Fib(0)=0, Fib(1)=1, Fib(2)=1, Fib(3)=2, Fib(4)=3, Fib(5)=5, Fib(6)=8, Fib(7)=13, +etc. + +But 1, 1, 2, 3, 5, 8 are the occurrences of our list! We can actually +demonstrate that to have an unbalanced tree, we have to take a list with +an occurrence based on the Fibonacci series (these values are minimal). +If the data to compress have m different bytes, when the tree is unbalanced, +the longest code need m-1 bits. In our little previous example where m=5, +the longest codes are associated to the bytes 100 and 115, respectively coded +0001b and 0000b. We can also say that to have an unbalanced tree we must have +at least 5+3+2+1+1=12=Fib(7)-1. To conclude about all that, with a coder that +uses m-1 bits, you must never have an input stream size over than Fib(m+2)-1, +otherwise, there could be a bug in the output stream. Of course, with my codecs +there will never be a bug because I can deal with binary code sizes of 1 to 256 +bits. Some encoder could use that with m=31, Fib(31+2)-1=3,524,577 and m=32, +Fib(32+2)-1=5,702,886. And an encoder that uses unisgned integer of 32 bits +shouldn't have a bug until about 4 Gb... + ++==========================================================+ +| The LZW encoding | ++==========================================================+ + +The LZW scheme is due to three searchers, i.e. Abraham Lempel and Jacob Ziv +worked on it in 1977, and Terry Welch achieved this scheme in 1984. + +LZW is patented in USA. This patent, number 4,558,302, is covered by Unisys +Corporation. You can usually write (without fees) software codecs which use +the LZW scheme but hardware companies can't do so. You may get a limited +licence by writting to: +Welch Licencing Department +Office of the General Counsel +M/S C1SW19 +Unisys corporation +Blue Bell +Pennsylvania, 19424 (USA) + +If you're occidental, you are surely using an LZW encoding every time you are +speaking, especially when you use a dictionary. Let's consider, for example, +the word "Cirrus". As you read a dictionary, you begin with "A", "Aa", and so +on. But a computer has no experience and it must suppose that some words +already exist. That is why with "Cirrus", it supposes that "C", "Ci", "Cir", +"Cirr", "Cirru", and "Cirrus" exist. Of course, being that this is a computer, +all these words are encoded as index numbers. Every time you go forward, you add +a new number associated to the new word. Being that a computer is byte-based +and not alphabetic-based, you have an initial dictionary of 256 letters instead +of our 26 ('A' to 'Z') letters. + +Example: Let's code "XYXYZ". First step, "X" is recognized in the initial +dictionary of 256 letters as the 89th. Second step, "Y" is read. Does "XY" +exist? No, then "XY" is stored as the word 256. You write in the output stream +the ASCII of "X", i.e. 88. Now "YX" is tested as not referenced in the current +dictionary. It is stored as the word 257. You write now in the output stream 89 +(ASCII of "Y"). "XY" is now met. But now "XY" is known as the reference 256. +Being that "XY" exists, you test the sequence with one more letter, i.e. "XYZ". +This last word is not referenced in the current dictionary. You write then the +value 256. Finally, you reach the last letter ("Z"). You add "YZ" as the +reference 258 but it is the last letter. That is why you just write the value +90 (ASCII of "Z"). + +Another encoding sample with the string "ABADABCCCABCEABCECCA". + ++----+-----+---------------+------+----------+-------------------------+------+ +|Step|Input|Dictionary test|Prefix|New symbol|Dictionary |Output| +| | | | | |D0=ASCII with 256 letters| | ++----+-----+---------------+------+----------+-------------------------+------+ +| 1 | "A" |"A" in D0 | "A" | "B" | D1=D0 | 65 | +| | "B" |"AB" not in D0 | | | and "AB"=256 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 2 | "A" |"B" in D1 | "B" | "A" | D2=D1 | 66 | +| | |"BA" not in D1 | | | and "BA"=257 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 3 | "D" |"A" in D2 | "A" | "D" | D3=D2 | 65 | +| | |"AD" not in D2 | | | and "AD"=258 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 4 | "A" |"D" in D3 | "D" | "A" | D4=D3 | 68 | +| | |"DA" not in D3 | | | and "DA"=259 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 5 | "B" |"A" in D4 | "AB" | "C" | D5=D4 | 256 | +| | "C" |"AB" in D4 | | | and "ABC"=260 | | +| | |"ABC" not in D4| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 6 | "C" |"C" in D5 | "C" | "C" | D6=D5 | 67 | +| | |"CC" not in D5 | | | and "CC"=261 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 7 | "C" |"C" in D6 | "CC" | "A" | D7=D6 | 261 | +| | "A" |"CC" in D6 | | | and "CCA"=262 | | +| | |"CCA" not in D6| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 8 | "B" |"A" in D7 | "ABC"| "E" | D8=D7 | 260 | +| | "C" |"AB" in D7 | | | and "ABCE"=263 | | +| | "E" |"ABC" in D7 | | | | | +| | <"ABCE" not in D7| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 9 | "A" |"E" in D8 | "E" | "A" | D9=D8 | 69 | +| | |"EA" not in D8 | | | and "EA"=264 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 10 | "B" |"A" in D9 |"ABCE"| "C" | D10=D9 | 263 | +| | "C" |"AB" in D9 | | | and "ABCEC"=265 | | +| | "E" |"ABC" in D9 | | | | | +| | "C" |"ABCE" in D9 | | | | | +| | <"ABCEC" not in D9> | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 11 | "C" |"C" in D10 | "CCA"| | | 262 | +| | "A" |"CC" in D10 | | | | | +| | <"CCA" not in D10| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ + +You will notice a problem with the above output: How to write a code of 256 +(for example) on 8 bits? It's simple to solve this problem. You just say that +the encoding starts with 9 bits and as you reach the 512th word, you use a +10-bits encoding. With 1024 words, you use 11 bits; with 2048 words, 12 bits; +and so on with all numbers of 2^n (n is positive). To better synchronize +the coder and the decoder with all that, most of implementations use two +additional references. The word 256 is a code of reinitialisation (the codec +must reinitialize completely the current dictionary to its 256 initial letters) +and the word 257 is a code of end of information (no more data to read). +Of course, you start your first new word as the code number 258. + +You can also do so as in the GIF file format and start with an initial +dictionary of 18 words to code an input stream with only letters coded on 4 bits +(you start with codes of 5 bits in the output stream!). The 18 initial words +are: 0 to 15 (initial letters), 16 (reinit the dictionary), and 17 (end of +information). First new word has code 18, second word, code 19, ... + +Important: You can consider that your dictionary is limited to 4096 different +words (as in GIF and TIFF file formats). But if your dictionary is full, you +can decide to send old codes *without* reinitializing the dictionary. All the +decoders must be compliant with this. This enables you to consider that it is +not efficient to reinitialize the full dictionary. Instead of this, you don't +change the dictionary and you send/receive (depending if it's a coder or a +decoder) existing codes in the full dictionary. + +My codecs are able to deal as well with most of initial size of data in the +initial dictionary as with full dictionary. + +Let's see how to decode an LZW encoding. We saw with true dynamical Huffman +scheme that you needed an header in the encoding codes. Any header is useless +in LZW scheme. When two successive bytes are read, the first must exist in the +dictionary. This code can be immediately decoded and written in the output +stream. If the second code is equal or less than the word number in the current +dictionary, this code is decoded as the first one. At the opposite, if the +second code is equal to the word number in dictionary plus one, this means you +have to write a word composed with the word (the sentence, not the code number) +of the last code plus the first character of the last code. In between, you make +appear a new word. This new word is the one you just sent to the output stream, +it means composed by all the letters of the word associated to the first code +and the first letter of the word of the second code. You continue the processing +with the second and third codes read in the input stream (of codes)... + +Example: Let's decode the previous encoding given a bit more above. + ++------+-------+----------------+----------+------------------+--------+ +| Step | Input | Code to decode | New code | Dictionary | Output | ++------+-------+----------------+----------+------------------+--------+ +| 1 | 65 | 65 | 66 | 65,66=256 | "A" | +| | 66 | | | | | ++------+-------+----------------+----------+------------------+--------+ +| 2 | 65 | 66 | 65 | 66,65=257 | "B" | ++------+-------+----------------+----------+------------------+--------+ +| 3 | 68 | 65 | 68 | 65,68=258 | "A" | ++------+-------+----------------+----------+------------------+--------+ +| 4 | 256 | 68 | 256 | 68,65=259 | "D" | ++------+-------+----------------+----------+------------------+--------+ +| 5 | 67 | 256 | 67 | 65,66,67=260 | "AB" | ++------+-------+----------------+----------+------------------+--------+ +| 6 | 261 | 67 | 261 | 67,67=261 | "C" | ++------+-------+----------------+----------+------------------+--------+ +| 7 | 260 | 261 | 260 | 67,67,65=262 | "CC" | ++------+-------+----------------+----------+------------------+--------+ +| 8 | 69 | 260 | 69 | 65,66,67,69=263 | "ABC" | ++------+-------+----------------+----------+------------------+--------+ +| 9 | 263 | 69 | 263 | 69,65=264 | "E" | ++------+-------+----------------+----------+------------------+--------+ +| 10 | 262 | 263 | 262 |65,66,67,69,67=256| "ABCE" | ++------+-------+----------------+----------+------------------+--------+ +| 11 | | 262 | | | "CCA" | ++------+-------+----------------+----------+------------------+--------+ + +Summary: The step 4 is an explicit example. The code to decode is 68 ("D" in +ASCII) and the new code is 256. The new word to add to the dictionary is the +letters of the first word plus the the first letter of the second code (code +256), i.e. 65 ("A" in ASCII) plus 68 ("D"). So the new word has the letters 68 +and 65 ("AD"). + +The step 6 is quite special. The first code to decode is referenced but the +second new code is not referenced being that the dictionary is limited to 260 +referenced words. We have to make it as the second previously given case, it +means you must take the word to decode plus its first letter, i.e. "C"+"C"="CC". +Be care, if any encountered code is *upper* than the dictionary size plus 1, it +means you have a problem in your data and/or your codecs are...bad! + +Tricks to improve LZW encoding (but it becomes a non-standard encoding): +- To limit the dictionary to an high amount of words (4096 words maximum enable +you to encode a stream of a maximmum 7,370,880 letters with the same dictionary) +- To use a dictionary of less than 258 if possible (example, with 16 color +pictures, you start with a dictionary of 18 words) +- To not reinitialize a dictionary when it is full +- To reinitialize a dictionary with the most frequent of the previous dictionary +- To use the codes from (current dictionary size+1) to (maximum dictionary size) +because these codes are not used in the standard LZW scheme. +Such a compression scheme has been used (successfully) by Robin Watts +. + ++==========================================================+ +| Summary | ++==========================================================+ + +------------------------------------------------- +RLE type 1: +Fastest compression. Good ratio for general purpose. +Doesn't need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 2: +Fast compression. Very good ratio in general (even for general purposes). +Need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 3: +Slowest compression. Good ratio on image file,quite middle for general purposes. +Need to read the data by twice. +Change line: +#define MAX_RASTER_SIZE 256 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +RLE type 4: +Slow compression. Good ratio on image file, middle in general purposes. +Change line: +#define MAX_RASTER_SIZE 66 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +Huffman: +Fast compression. Good ratio on text files and similar, middle for general +purposes. Interesting method to use to compress a buffer already compressed by +RLE types 1 or 2 methods... +Decoding fast. +------------------------------------------------- +LZW: +Quite fast compression. Good, see even very good ratio, for general purposes. +Bigger the data are, better the compression ratio is. +Decoding quite fast. +------------------------------------------------- + +The source codes work on all kinds of computers with a C compiler. +With the compiler, optimize the speed run option instead of space option. +With UNIX system, it's better to compile them with option -O. +If you don't use a GNU compiler, the source file MUST NOT have a size +over 4 Gb for RLE 2, 3, and Huffman, because I count the number +of occurrences of the bytes. +So, with GNU compilers, 'unsigned lont int' is 8 bytes instead of 4 bytes +(as normal C UNIX compilers and PCs' compilers, such as Microsoft C++ +and Borland C++). +Actually: +* Normal UNIX compilers, => 4 Gb (unsigned long int = 4 bytes) + Microsoft C++ and Borland C++ for PCs +* GNU UNIX compilers => 17179869184 Gb (unsigned long int = 8 bytes) + ++==========================================================+ +| END | ++==========================================================+ diff --git a/all_pairs/source/huff_dec/huff_dec.c b/all_pairs/source/huff_dec/huff_dec.c new file mode 100644 index 0000000..48bdf4b --- /dev/null +++ b/all_pairs/source/huff_dec/huff_dec.c @@ -0,0 +1,393 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: huff_dec + + Author: David Bourgin (David.Bourgin@ufrima.imag.fr) + + Function: Example of Huffman decoding + + Source: ftp://turing.imag.fr/pub/compression/ (1994-09-26) + + Original name: dcodhuff.c + + Changes: I/O to char arrays instead of file i/o. + Dynamic memory allocation replaced by array. + + License: + +The source code files (codrl1.c, dcodrl1.c, codrle2.c, dcodrle2.c, codrle3.c, +dcodrle3.c, codrle4.c, dcodrle4.c, codhuff.c, dcodhuff.c) are copyrighted. +They have been uploaded on ftp in turing.imag.fr (129.88.31.7):/pub/compression +on 22/5/94 and have been modified on 22/9/94. +(c) David Bourgin - 1994 +The source codes I provide have no buggs (!) but being that I make them +available for free I have some notes to make. They can change at any time +without notice. I assume no responsability or liability for any errors or +inaccurracies, make no warranty of any kind (express, implied or statutory) +with respect to this publication and expressly disclaim any and all warranties +of merchantability, fitness for particular purposes. Of course, if you have +some problems to use the information presented here, I will try to help you if +I can. + +If you include the source codes in your application, here are the conditions: +- You have to put my name in the header of your source file (not in the +excutable program if you don't want) (this item is a must) +- I would like to see your resulting application, if possible (this item is not +a must, because some applications must remain secret) +- Whenever you gain money with your application, I would like to receive a very +little part in order to be encouraged to update my source codes and to develop +new schemes (this item is not a must) + +*/ + + +/* + Declaration of types +*/ + + +#include "../extra.h" +typedef struct s_tree { + unsigned int byte; /* A byte has to be coded as an unsigned integer to + allow a node to have a value over 255 */ + struct s_tree *left_ptr; + struct s_tree *right_ptr; +} huff_dec_t_tree; + +typedef struct { + unsigned char bits[32]; + unsigned int bits_nb; + unsigned char presence; +} t_bin_val; + + +/* + Forward declaration of functions +*/ + +void huff_dec_init( void ); +int huff_dec_return( void ); +int huff_dec_end_of_data(); +int huff_dec_read_byte(); +void huff_dec_write_byte( char ch ); +unsigned char huff_dec_read_code_1_bit(); +unsigned int huff_dec_read_code_n_bits( unsigned int n ); +void huff_dec_read_header( t_bin_val codes_table[257] ); +huff_dec_t_tree *huff_dec_tree_encoding( t_bin_val codes_table[257], + huff_dec_t_tree heap[514] ); +void huff_dec_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +static int huff_dec_input_pos; +static int huff_dec_output_pos; +static char huff_dec_output[1024]; +unsigned char huff_dec_byte_nb_to_read = 0; +unsigned int huff_dec_val_to_read = 0; + + +/* + Initialization- and return-value-related functions +*/ + +#define huff_dec_plaintext_len 600 +static const char *huff_dec_plaintext = + "You are doubtless asking \"How can I reduce the data size without losing " + "some informations?\". It's easy to answer to this question. I'll only take " + "an example. I'm sure you have heard about the morse. This system established " + "in the 19th century use a scheme very close to the huffman one. In the morse " + "you encode the letters to transmit with two kinds of signs. If you encode " + "these two sign possibilities in one bit, the symbol 'e' is transmitted in a " + "single bit and the symbols 'y' and 'z' need four bits. Look at the symbols " + "in the text you are reading, you'll fast understand the compression ratio..."; + +#define huff_dec_encoded_len 419 +static unsigned char huff_dec_encoded[huff_dec_encoded_len] = { + 128, 0, 0, 0, 80, 133, 32, 32, 128, 100, 4, 32, 63, 239, 255, 240, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 7, 167, 21, 129, 232, 69, 120, 132, 217, 20, 162, 19, 164, 39, 133, + 252, 138, 105, 20, 194, 19, 129, 240, 172, 138, 248, 150, 11, 11, 240, 201, + 68, 64, 114, 53, 17, 42, 37, 195, 128, 212, 116, 194, 41, 98, 52, 51, + 12, 132, 112, 244, 3, 36, 33, 52, 39, 135, 164, 33, 62, 156, 87, 14, + 110, 22, 87, 50, 85, 198, 99, 142, 140, 194, 81, 78, 158, 84, 129, 254, + 129, 248, 110, 179, 159, 192, 145, 133, 184, 184, 28, 210, 96, 146, 73, 10, + 226, 21, 83, 152, 74, 13, 111, 132, 199, 202, 219, 241, 74, 193, 167, 105, + 222, 31, 147, 6, 55, 31, 129, 40, 232, 52, 153, 160, 148, 18, 36, 197, + 45, 216, 202, 86, 30, 31, 177, 90, 133, 138, 248, 23, 81, 195, 160, 100, + 215, 93, 50, 185, 225, 251, 23, 6, 230, 225, 229, 112, 71, 80, 96, 141, + 205, 176, 230, 85, 196, 9, 24, 93, 90, 121, 225, 76, 68, 152, 63, 25, + 107, 140, 101, 204, 214, 77, 26, 194, 96, 18, 48, 77, 210, 137, 1, 253, + 4, 230, 248, 56, 240, 224, 111, 163, 95, 10, 12, 223, 7, 234, 167, 129, + 40, 36, 96, 135, 125, 245, 250, 2, 198, 120, 127, 0, 145, 133, 213, 167, + 135, 149, 195, 67, 235, 108, 9, 24, 87, 17, 102, 152, 37, 4, 222, 131, + 188, 144, 73, 36, 128, 73, 20, 81, 152, 177, 133, 248, 28, 165, 131, 120, + 127, 240, 242, 184, 104, 125, 109, 129, 35, 30, 4, 145, 65, 202, 88, 9, + 138, 103, 44, 205, 100, 167, 24, 152, 11, 24, 51, 37, 66, 9, 24, 31, + 174, 202, 212, 49, 152, 18, 96, 155, 208, 119, 146, 45, 97, 48, 56, 28, + 194, 90, 224, 204, 144, 232, 176, 36, 96, 126, 187, 43, 83, 12, 121, 129, + 209, 96, 197, 35, 2, 54, 176, 249, 92, 208, 204, 145, 188, 41, 170, 180, + 71, 16, 36, 96, 126, 187, 43, 83, 19, 0, 145, 129, 100, 209, 15, 43, + 135, 55, 6, 238, 180, 194, 90, 17, 229, 115, 21, 168, 251, 140, 131, 162, + 217, 166, 93, 22, 4, 140, 31, 91, 166, 55, 25, 202, 192, 111, 20, 171, + 207, 39, 192, +}; + + +void huff_dec_init( void ) +{ + huff_dec_input_pos = 0; + huff_dec_output_pos = 0; +} + + +int huff_dec_return( void ) +{ + int i; + _Pragma( "loopbound min 1 max 600" ) + for ( i = 0; i < huff_dec_plaintext_len; i++ ) { + if ( huff_dec_plaintext[i] != huff_dec_output[i] ) return i + 1; + } + return 0; +} + + +/* + Input / output functions +*/ + +int huff_dec_end_of_data() +{ + return huff_dec_input_pos >= huff_dec_encoded_len; +} + + +int huff_dec_read_byte() +{ + return huff_dec_encoded[huff_dec_input_pos++]; +} + + +void huff_dec_write_byte( char ch ) +{ + huff_dec_output[huff_dec_output_pos++] = ch; +} + + +unsigned char huff_dec_read_code_1_bit() +/* Returned parameters: Returns an unsigned integer with the 0-bit (on the + right of the integer) valid + Action: Reads the next bit in the stream of data to compress + Errors: An input/output error could disturb the running of the program + The source must have enough bits to read +*/ +{ + if ( huff_dec_byte_nb_to_read ) { + huff_dec_byte_nb_to_read--; + return ( ( huff_dec_val_to_read >> huff_dec_byte_nb_to_read ) & 1 ); + } else { + huff_dec_val_to_read = huff_dec_read_byte(); + huff_dec_byte_nb_to_read = 7; + return ( ( huff_dec_val_to_read >> 7 ) & 1 ); + } +} + + +unsigned int huff_dec_read_code_n_bits( unsigned int n ) +/* Returned parameters: Returns an unsigned integer with the n-bits (on the + right of the integer) valid + Action: Reads the next n bits in the stream of data to compress + Errors: An input/output error could disturb the running of the program + The source must have enough bits to read +*/ +{ + unsigned int result = 0; + unsigned i = n; + + _Pragma ( "loopbound min 1 max 1" ) + while ( i ) { + _Pragma ( "loopbound min 0 max 2" ) + while ( ( huff_dec_byte_nb_to_read < 9 ) && ( !huff_dec_end_of_data() ) ) { + huff_dec_val_to_read = ( huff_dec_val_to_read << 8 ) + huff_dec_read_byte(); + huff_dec_byte_nb_to_read += 8; + } + if ( i >= huff_dec_byte_nb_to_read ) { + result = ( result << huff_dec_byte_nb_to_read ) + huff_dec_val_to_read; + i -= huff_dec_byte_nb_to_read; + huff_dec_byte_nb_to_read = 0; + } else { + result = ( result << i ) + ( ( huff_dec_val_to_read >> + ( huff_dec_byte_nb_to_read - i ) ) & ( ( 1 << i ) - 1 ) ); + huff_dec_byte_nb_to_read -= i; + i = 0; + } + } + return ( result ); +} + + +void huff_dec_read_header( t_bin_val codes_table[257] ) +/* Returned parameters: The contain of 'codes_table' is modified + Action: Rebuilds the binary encoding array by using the header + Errors: An input/output error could disturb the running of the program +*/ +{ + unsigned int i, j; + unsigned num_byte; + + _Pragma ( "loopbound min 257 max 257" ) + for ( i = 0; i < 257; i++ ) { + codes_table[i].bits_nb = 0; + _Pragma ( "loopbound min 32 max 32" ) + for ( j = 0; j < 32; j++ ) { + codes_table[i].bits[j] = 0; + } + } + + /* == Decoding of the first part of the header === */ + if ( huff_dec_read_code_1_bit() ) + /* First bit=0 => Present bytes coded on n*8 bits + =1 => Present bytes coded on 256 bits */ + _Pragma ( "loopbound min 256 max 256" ) + for ( i = 0; i <= 255; i++ ) + codes_table[i].presence = huff_dec_read_code_1_bit(); + else { + i = huff_dec_read_code_n_bits( 5 ) + 1; + _Pragma ( "loopbound min 1 max 32" ) + while ( i ) { + codes_table[huff_dec_read_code_n_bits( 8 )].presence = 1; + i--; + } + } + codes_table[256].presence = 1; + /* Presence of a fictive 256-byte is enforced! */ + + /* == Decoding the second part of the header == */ + _Pragma ( "loopbound min 257 max 257" ) + for ( i = 0; i <= 256; i++ ) + if ( codes_table[i].presence ) { + if ( huff_dec_read_code_1_bit() ) + /* First bit=0 => 5 bits of binary length-1 followed by a binary word + =1 => 8 bits of binary length-1 followed by a binary word */ + j = huff_dec_read_code_n_bits( 8 ) + 1; + else j = huff_dec_read_code_n_bits( 5 ) + 1; + codes_table[i].bits_nb = j; + /* Reading of a binary word */ + num_byte = ( j - 1 ) >> 3; + if ( j & 7 ) { + /* Reads the bits that takes less than one byte */ + codes_table[i].bits[num_byte] = + ( unsigned char )huff_dec_read_code_n_bits( j & 7 ); + j -= j & 7; + num_byte--; + } + + _Pragma ( "loopbound min 0 max 1" ) + while ( j >= 8 ) { + /* Reads the bits that takes one byte, at least */ + codes_table[i].bits[num_byte] = + ( unsigned char )huff_dec_read_code_n_bits( 8 ); + j -= 8; + num_byte--; + } + } +} + + +huff_dec_t_tree *huff_dec_tree_encoding( t_bin_val codes_table[257], + huff_dec_t_tree heap[514] ) +/* Returned parameters: A binary tree is returned + Action: Returns the decoding binary tree built from 'codes_table' + Errors: None +*/ +{ + unsigned int i; + unsigned int j; + unsigned int heap_top = 0; + huff_dec_t_tree *ptr_tree; + huff_dec_t_tree *current_node; + + ptr_tree = &heap[heap_top++]; + ptr_tree->byte = 257; + ptr_tree->left_ptr = 0; + ptr_tree->right_ptr = 0; + _Pragma ( "loopbound min 257 max 257" ) + for ( i = 0; i <= 256; i++ ) { + _Pragma ( "loopbound min 0 max 9" ) + for ( current_node = ptr_tree, j = codes_table[i].bits_nb; j; j-- ) { + if ( codes_table[i].bits[( j - 1 ) >> 3] & ( 1 << ( ( + j - 1 ) & 7 ) ) ) + if ( current_node->left_ptr == 0 ) { + current_node->left_ptr = &heap[heap_top++]; + current_node = current_node->left_ptr; + current_node->left_ptr = 0; + current_node->right_ptr = 0; + } else current_node = current_node->left_ptr; + else + if ( current_node->right_ptr == 0 ) { + current_node->right_ptr = &heap[heap_top++]; + current_node = current_node->right_ptr; + current_node->left_ptr = 0; + current_node->right_ptr = 0; + } else current_node = current_node->right_ptr; + if ( j == 1 ) + current_node->byte = i; + else current_node->byte = 257; + } + }; + return ( ptr_tree ); +} + + +void _Pragma( "entrypoint" ) huff_dec_main( void ) +/* Returned parameters: None + Action: Decompresses with Huffman method all bytes read by the function + 'read_code_1_bit' and 'read_code_n_bits' + Errors: An input/output error could disturb the running of the program +*/ +{ + t_bin_val encoding_table[257]; + huff_dec_t_tree heap[514]; /* space for dynamically allocated nodes */ + huff_dec_t_tree *ptr_tree; + huff_dec_t_tree *current_node; + + if ( !huff_dec_end_of_data() ) { /* Are there data to compress? */ + huff_dec_read_header( encoding_table ); + ptr_tree = huff_dec_tree_encoding( encoding_table, heap ); + _Pragma ( "loopbound min 602 max 602" ) + do { + current_node = ptr_tree; + _Pragma ( "loopbound min 3 max 9" ) + while ( current_node->byte == 257 ) + if ( huff_dec_read_code_1_bit() ) + /* Bit=1 => Got to left in the node of the tree + =0 => Got to right in the node of the tree */ + current_node = current_node->left_ptr; + else current_node = current_node->right_ptr; + if ( current_node->byte <= 255 ) + huff_dec_write_byte( current_node->byte ); + } while ( current_node->byte != 256 ); + } +} + + +int main( int argc, char **argv ) +{ + //SET_UP + int jobsComplete; + int maxJobs=5; + for (jobsComplete=-1; jobsCompletesource_memory_end) +#define read_byte() (*(source_ptr++)) + +If you want to compress *to* memory, before entering in a xxxcoding procedure +('xxx' is the actual extension to replace with a given codec), you have to add +a pointer. Note that the pointer 'dest_memory_base' is not to add, it is just +given there to specify the address of the destination memory zone you are +going to encode or decode. + +unsigned char *dest_memory_base, /* Base of the destination memory */ + *dest_ptr; /* Used in the xxxcoding procedure */ +void pre_start() +{ dest_ptr=dest_memory_base; + xxxcoding(); +} + +Of course, you can combine both from and to memory in the pre_start() procedure. +The files dest_file and source_file handled in the main() function are +to remove... + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + xxxcoding(); +} + +In fact, to write to memory, the problem is in the write_byte(x) procedure. +This problem exists because your destination zone can either be a static +zone or a dynamically allocated zone. In the two cases, you have to check +if there is no overflow, especially if the coder is not efficient and must +produce more bytes than you reserved in memory. + +In the first case, with a *static* zone, write_byte(x) macro should look like +that: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + exit(1); \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +In the static version, the pre_start() procedure is to modify as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=...; /* Set up to the actual destination zone length */ + current_size=0; /* Number of written bytes */ + xxxcoding(); +} +Otherwise, dest_ptr is a zone created by the malloc instruction and you can try +to resize the allocated zone with the realloc instruction. Note that I increment +the zone one kilo-bytes by one kylo-bytes. You have to add two other variables: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + { dest_zone_length += 1024; \ + if ((dest_ptr=(unsigned char *)realloc(dest_ptr,dest_zone_length*sizeof(unsigned char)))==NULL) \ + exit(1); /* You can't compress in memory \ + => I exit but *you* can make a routine to swap on disk */ \ + } \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +With the dynamically allocated version, change the pre_start() routine as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=1024; + if ((dest_ptr=(unsigned char *)malloc(dest_zone_length*sizeof(unsigned char)))==NULL) + exit(1); /* You need at least 1 kb in the dynamical memory ! */ + current_size=0; /* Number of written bytes */ + xxxcoding(); + /* Handle the bytes in dest_ptr but don't forget to free these bytes with: + free(dest_ptr); + */ +} + +The previously given macros work as: + +void demo() /* The file opening, closing and variables + must be set up by the calling procedure */ +{ unsigned char byte; + /* And not 'char byte' (!) */ + while (!end_of_data()) + { byte=read_byte(); + printf("Byte read=%c\n",byte); + } +} + +You must not change the rest of the program unless you're really sure and +really need to do it! + ++==========================================================+ +| The RLE encoding | ++==========================================================+ + +RLE is an acronym that stands for Run Length Encoding. You may encounter it +as an other acronym: RLC, Run Length Coding. + +The idea in this scheme is to recode your data with regard to the repetition +frames. A frame is one or more bytes that occurr one or several times. + +There are several means to encode occurrences. So, you'll have several codecs. +For example, you may have a sequence such as: +0,0,0,0,0,0,255,255,255,2,3,4,2,3,4,5,8,11 + +Some codecs will only deal with the repetitions of '0' and '255' but some other +will deal with the repetitions of '0', '255', and '2,3,4'. + +You have to keep in your mind something important based on this example. A codec +won't work on all the data you will try to compress. So, in case of non +existence of sequence repetitions, the codecs based on RLE schemes must not +display a message to say: "Bye bye". Actually, they will try to encode these +non repeted data with a value that says "Sorry, I only make a copy of the inital +input". Of course, a copy of the input data with an header in front of this copy +will make a biggest output data but if you consider the whole data to compress, +the encoding of repeated frames will take less space than the encoding +of non-repeated frames. + +All of the algorithms with the name of RLE have the following look with three +or four values: +- Value saying if there's a repetition +- Value saying how many repetitions (or non repetition) +- Value of the length of the frame (useless if you just encode frame +with one byte as maximum length) +- Value of the frame to repeat (or not) + +I gave four algorithms to explain what I say. + +*** First RLE scheme *** + +The first scheme is the simpliest I know, and looks like the one used in MAC +system (MacPackBit) and some image file formats such as Targa, PCX, TIFF, ... + +Here, all compressed blocks begin with a byte, named header, which description +is: + +Bits 7 6 5 4 3 2 1 0 +Header X X X X X X X X + +Bits 7: Compression status (1=Compression applied) + 0 to 6: Number of bytes to handle + +So, if the bit 7 is set up to 0, the 0 to 6 bits give the number of bytes +that follow (minus 1, to gain more over compress) and that were not compressed +(native bytes). If the bit 7 is set up to 1, the same 0 to 6 bits give +the number of repetition (minus 2) of the following byte. + +As you see, this method only handle frame with one byte. + +Additional note: You have 'minus 1' for non-repeated frames because you must +have at least one byte to compress and 'minus 2' for repeated frames because the +repetition must be 2, at least. + +Compression scheme: + + First byte=Next + /\ + / \ +Count the byte Count the occurrence of NON identical +occurrences bytes (maximum 128 times) +(maximum 129 times) and store them in an array + | | + | | + 1 bit '1' 1 bit '0' ++ 7 bits giving + 7 bits giving + the number (-2) the number (-1) + of repetitions of non repetition ++ repeated byte + n non repeated bytes + | | + 1xxxxxxx,yyyyyyyy 0xxxxxxx,n bytes +[-----------------] [----------------] + +Example: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 1,255,15, | -1 + 255,255, | 128,255, | 0 + 15,15, | 128,15, | 0 + 255,255,255, | 129,255, | +1 + 15,15,15, | 129,15, | +1 + 255,255,255,255, | 130,255, | +2 + 15,15,15,15 | 130,15 | +2 + +See codecs source codes: codrle1.c and dcodrle1.c + +*** Second RLE scheme *** + +In the second scheme of RLE compression you look for the less frequent byte +in the source to compress and use it as an header for all compressed block. + +In the best cases, the occurrence of this byte is zero in the data to compress. + +Two possible schemes, firstly with handling frames with only one byte, +secondly with handling frames with one byte *and* more. The first case is +the subject of this current compression scheme, the second is the subject +of next compression scheme. + +For the frame of one byte, header byte is written in front of all repetition +with at least 4 bytes. It is then followed by the repetition number minus 1 and +the repeated byte. +Header byte, Occurrence number-1, repeated byte + +If a byte don't repeat more than tree times, the three bytes are written without +changes in the destination stream (no header nor length, nor repetition in front +or after theses bytes). + +An exception: If the header byte appears in the source one, two, three and up +times, it'll be respectively encoded as following: +- Header byte, 0 +- Header byte, 1 +- Header byte, 2 +- Header byte, Occurrence number-1, Header byte + +Example, let's take the previous example. A non frequent byte is zero-ASCII +because it never appears. + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 255,15, | -1 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 0,3,255, | -1 + 15,15,15,15 | 0,3,15 | -1 + +If the header would appear, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 0, | 0,0, | +1 + 255, | 255, | 0 + 0,0, | 0,1, | 0 + 15, | 15, | 0 + 0,0,0, | 0,2, | -1 + 255, | 255, | 0 + 0,0,0,0 | 0,3,0 | -1 + +See codecs source codes: codrle2.c and dcodrle2.c + +*** Third RLE scheme *** + +It's the same idea as the second scheme but we can encode frames with +more than one byte. So we have three cases: + +- If it was the header byte, whatever is its occurrence, you encode it with: +Header byte,0,number of occurrence-1 +- For frames which (repetition-1)*length>3, encode it as: +Header byte, Number of frame repetition-1, frame length-1,bytes of frame +- If no previous cases were detected, you write them as originally (no header, +nor length, nor repetition in front or after theses bytes). + +Example based on the previous examples: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +----------------------------------------------------------------------------- + 255,15, | 255,15, | 0 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 255,255,255,255, | 0 + 15,15,15,15, | 15,15,15,15, | 0 + 16,17,18,16,17,18, |16,17,18,16,17,18,| 0 + 255,255,255,255,255, | 0,4,0,255, | -1 + 15,15,15,15,15, | 0,4,0,15, | -1 + 16,17,18,16,17,18,16,17,18,| 0,2,2,16,17,18, | -3 + 16,17,18,19,16,17,18,19 |0,1,3,16,17,18,19 | -1 + +If the header (value 0) would be met, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 0, | 0,0,0, | +2 + 255, | 255, | 0 + 0,0, | 0,0,1, | +1 + 15, | 15, | 0 + 0,0,0, | 0,0,2, | 0 + 255, | 255, | 0 + 0,0,0,0 | 0,0,3 | -1 + +See codecs source codes: codrle3.c and dcodrle3.c + +*** Fourth RLE scheme *** + +This last RLE algorithm better handles repetitions of any kind (one byte +and more) and non repetitions, including few non repetitions, and does not +read the source by twice as RLE type 3. + +Compression scheme is: + + First byte=Next byte? + /\ + Yes / \ No + / \ + 1 bit '0' 1 bit '1' + / \ + / \ + Count the Motif of several + occurrences repeated byte? + of 1 repeated ( 65 bytes repeated + byte (maximum 257 times maxi) + 16449 times) /\ + /\ / \ + / \ / \ + / \ / \ + / \ / \ + 1 bit '0' 1 bit '1' 1 bit '0' 1 bit '1' ++ 6 bits + 14 bits + 6 bits of | +giving the giving the the length Number of non repetition +length (-2) length (-66) of the motif (maximum 8224) +of the of the + 8 bits of /\ +repeated byte repeated byte the number (-2) < 33 / \ > 32 ++ repeated byte + repeated byte of repetition / \ + | | + bytes of the 1 bit '0' 1 bit '1' + | | motif + 5 bits of + 13 bits + | | | the numer (-1) of the + | | | of non number (-33) + | | | repetition of repetition + | | | + non + non + | | | repeated repeated + | | | bytes bytes + | | | | | + | | | | 111xxxxx,xxxxxxxx,n bytes + | | | | [-------------------------] + | | | | + | | | 110xxxxx,n bytes + | | | [----------------] + | | | + | | 10xxxxxx,yyyyyyyy,n bytes + | | [-------------------------] + | | + | 01xxxxxx,xxxxxxxx,1 byte + | [------------------------] + | + 00xxxxxx,1 byte +[---------------] + +Example, same as previously: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 255,15 | 11000001b,255,15, | +1 + 255,255 | 00000000b,255, | 0 + 15,15 | 00000000b,15, | 0 + 255,255,255 | 00000001b,255, | -1 + 15,15,15 | 00000001b,15, | -1 + 255,255,255,255 | 00000010b,255, | -2 + 15,15,15,15 | 00000010b,15, | -2 + 16,17,18,16,17,18 |10000001b,0,16,17,18,| -1 + 255,255,255,255,255 | 00000011b,255, | -3 + 15,15,15,15,15 | 00000011b,15, | -3 + 16,17,18,16,17,18,16,17,18 | 10000001b,16,17,18, | -4 + 16,17,18,19,16,17,18,19 |10000010b,16,17,18,19| -2 + ++==========================================================+ +| The Huffman encoding | ++==========================================================+ + +This method comes from the searcher who established the algorithm in 1952. +This method allows both a dynamic and static statistic schemes. A statistic +scheme works on the data occurrences. It is not as with RLE where you had +a consideration of the current occurrence of a frame but rather a consideration +of the global occurrences of each data in the input stream. In this last case, +frames can be any kinds of sequences you want. On the other hand, Huffman +static encoding appears in some compressers such as ARJ on PCs. This enforces +the encoder to consider every statistic as the same for all the data you have. +Of course, the results are not as good as if it were a dynamic encoding. +The static encoding is faster than the dynamic encoding but the dynamic encoding +will be adapted to the statistic of the bytes of the input stream and will +of course become more efficient by producing shortest output. + +The main idea in Huffman encoding is to re-code every byte with regard to its +occurrence. The more frequent bytes in the data to compress will be encoded with +less than 8 bits and the others could need 8 bits see even more to be encoded. +You immediately see that the codes associated to the different bytes won't have +identical size. The Huffman method will actually require that the binary codes +have not a fixed size. We speak then about variable length codes. + +The dynamical Huffman scheme needs the binary trees for the encoding. This +enables you to obtain the best codes, adapted to the source data. +The demonstration won't be given there. To help the neophyt, I will just explain +what is a binary tree. + +A binary tree is special fashion to represent the data. A binary tree is +a structure with an associated value with two pointers. The term of binary has +been given because of the presence of two pointers. Because of some conventions, +one of the pointer is called left pointer and the second pointer is called right +pointer. Here is a visual representation of a binary tree. + + Value + / \ + / \ + Value Value + / \ / \ +... ... ... ... + +One problem with a binary encoding is a prefix problem. A prefix is the first +part of the representation of a value, e.g. "h" and "he" are prefixes of "hello" +but not "el". To understand the problem, let's code the letters "A", "B", "C", +"D", and "E" respectively as 00b, 01b, 10b, 11b, and 100b. When you read +the binary sequence 00100100b, you are unable to say if this comes from "ACBA" +or "AEE". To avoid such situations, the codes must have a prefix property. +And the letter "E" mustn't begin with the sequence of an other code. With "A", +"B", "C", "D", and "E" respectively affected with 1b, 01b, 001b, 0001b, and +0000b, the sequence 1001011b will only be decoded as "ACBA". + + 1 0 +<- /\ -> + / \ + "A" /\ + "B" \ + /\ + "C" \ + /\ + "D" "E" + +As you see, with this tree, an encoding will have the prefix property +if the bytes are at the end of each "branch" and you have no byte at the "node". +You also see that if you try to reach a character by the right pointer you add +a bit set to 0 and by the left pointer, you add a bit set to 1 to the current +code. The previous *bad* encoding provide the following bad tree: + + /\ + / \ + / \ + /\ /\ + / \ "B" "A" + / \ +"D" "C"\ + / \ + "E" + +You see here that the coder shouldn't put the "C" at a node... + +As you see, the largest binary code are those with the longest distance +from the top of the tree. Finally, the more frequent bytes will be the highest +in the tree in order you have the shortest encoding and the less frequent bytes +will be the lowest in the tree. + +From an algorithmic point of view, you make a list of each byte you encountered +in the stream to compress. This list will always be sorted. The zero-occurrence +bytes are removed from this list. You take the two bytes with the smallest +occurrences in the list. Whenever two bytes have the same "weight", you take two +of them regardless to their ASCII value. You join them in a node. This node will +have a fictive byte value (256 will be a good one!) and its weight will be +the sum of the two joined bytes. You replace then the two joined bytes with +the fictive byte. And you continue so until you have one byte (fictive or not) +in the list. Of course, this process will produce the shortest codes if the list +remains sorted. I will not explain with arcana hard maths why the result +is a set of the shortest bytes... + +Important: I use as convention that the right sub-trees have a weight greater +or equal to the weight of the left sub-trees. + +Example: Let's take a file to compress where we notice the following +occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +We will begin by joining the bytes 83 and 222. This will produce a fictive node +1 with a weight of 20+5=25. + +(Fictive 1,25) + /\ + / \ +(222,5) (83,20) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 1 | 25 + 77 | 24 + 115 | 21 + +Note that the list is sorted... The smallest values in the frequences are 21 and +24. That is why we will take the bytes 77 and 115 to build the fictive node 2. + +(Fictive 2,45) + /\ + / \ +(115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 2 | 45 + Fictive 1 | 25 + +The nodes with smallest weights are the fictive 1 and 2 nodes. These are joined +to build the fictive node 3 whose weight is 40+25=70. + + (Fictive 3,70) + / \ + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 3 | 70 + +The fictive node 3 is linked to the byte 31. Total weight: 280+70=350. + + (Fictive 4,350) + / \ + / \ + / \ + / \ (31,280) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 4 | 350 + 0 | 338 + 255 | 300 + +As you see, being that we sort the list, the fictive node 4 has become the first +of the list. We join the bytes 0 and 255 in a same fictive node, the number 5 +whose weight is 338+300=638. + +(Fictive 5,638) + /\ + / \ +(255,300) (0,338) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 5 | 638 + Fictive 4 | 350 + +The fictive nodes 4 and 5 are finally joined. Final weight: 638+350=998 bytes. +It is actually the total byte number in the initial file: 338+300+24+21+20+5. + + (Tree,998) + 1 / \ 0 + <- / \ -> + / \ + / \ + / \ + / \ / \ + / \ / \ + / \ / \ + / \ (31,280) (255,300) (0,338) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Bytes | Huffman codes | Frequences | Binary length*Frequence +------------------------------------------------------------ + 0 | 00b | 338 | 676 + 255 | 01b | 300 | 600 + 31 | 10b | 280 | 560 + 77 | 1101b | 24 | 96 + 115 | 1100b | 21 | 84 + 83 | 1110b | 20 | 80 + 222 | 1111b | 5 | 20 + +Results: Original file size: (338+300+280+24+21+20+5)*8=7904 bits (=998 bytes) +versus 676+600+560+96+84+80+20=2116 bits, i.e. 2116/8=265 bytes. + +Now you know how to code an input stream. The last problem is to decode all this +stuff. Actually, when you meet a binary sequence you can't say whether it comes +from such byte list or such other one. Furthermore, if you change the occurrence +of one or two bytes, you won't obtain the same resulting binary tree. Try for +example to encode the previous list but with the following occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 255 | 418 + 0 | 300 + 31 | 100 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +As you can observe it, the resulting binary tree is quite different, we had yet +the same initial bytes. To not be in such a situation we will put an header +in front of all data. I can't comment longly this header but I can say +I minimize it as much as I could. The header is divided into two parts. +The first part of this header looks closely to a boolean table (coded more or +less in binary to save space) and the second part provide to the decoder +the binary code associated to each byte encountered in the original input +stream. + +Here is a summary of the header: + +First part +---------- + First bit + / \ + 1 / \ 0 + / \ + 256 bits set to 0 or 1 5 bits for the number n (minus 1) + depending whether the of bytes encountered + corresponding byte was in the file to compres + in the file to compress | + (=> n bits set to 1, \ / + n>32) n values of 8-bits (n<=32) + \ / + \ / + \ / +Second part | +----------- | + | + +------------->| +(n+1) times | | +(n bytes of | First bit? +the values | / \ +encountered | 1 / \ 0 +in the | / \ +source file | 8 bits of 5 bits of the ++ the code | the length length (-1) +of a | (-1) of the of the following +fictive | following binary +byte | binary code code +to stop the | (length>32) (length<=32) +decoding. | \ / +The fictive | \ / +is set to | \ / +256 in the | | +Huffman | binary code +-tree of | | +encoding) +--------------| + | + Binary encoding of the source file + | + Code of end of encoding + | + + +With my codecs I can handle binary sequences with a length of 256 bits. +This correspond to encode all the input stream from one byte to infinite length. +In fact if a byte had a range from 0 to 257 instead of 0 to 255, I would have a +bug with my codecs with an input stream of at least 370,959,230,771,131,880,927, +453,318,055,001,997,489,772,178,180,790,105 bytes !!! + +Where come this explosive number? In fact, to have a severe bug, I must have +a completely unbalanced tree: + + Tree + /\ + \ + /\ + \ + /\ + \ + ... + /\ + \ + /\ + +Let's take the following example: + +Listed bytes | Frequences (Weight) +---------------------------------- + 32 | 5 + 101 | 3 + 97 | 2 + 100 | 1 + 115 | 1 + +This produces the following unbalanced tree: + + Tree + /\ +(32,5) \ + /\ + (101,3) \ + /\ + (97,2) \ + /\ + (115,1) (100,1) + +Let's speak about a mathematical series: The Fibonacci series. It is defined as +following: + +{ Fib(0)=0 +{ Fib(1)=1 +{ Fib(n)=Fib(n-2)+Fib(n-1) + +Fib(0)=0, Fib(1)=1, Fib(2)=1, Fib(3)=2, Fib(4)=3, Fib(5)=5, Fib(6)=8, Fib(7)=13, +etc. + +But 1, 1, 2, 3, 5, 8 are the occurrences of our list! We can actually +demonstrate that to have an unbalanced tree, we have to take a list with +an occurrence based on the Fibonacci series (these values are minimal). +If the data to compress have m different bytes, when the tree is unbalanced, +the longest code need m-1 bits. In our little previous example where m=5, +the longest codes are associated to the bytes 100 and 115, respectively coded +0001b and 0000b. We can also say that to have an unbalanced tree we must have +at least 5+3+2+1+1=12=Fib(7)-1. To conclude about all that, with a coder that +uses m-1 bits, you must never have an input stream size over than Fib(m+2)-1, +otherwise, there could be a bug in the output stream. Of course, with my codecs +there will never be a bug because I can deal with binary code sizes of 1 to 256 +bits. Some encoder could use that with m=31, Fib(31+2)-1=3,524,577 and m=32, +Fib(32+2)-1=5,702,886. And an encoder that uses unisgned integer of 32 bits +shouldn't have a bug until about 4 Gb... + ++==========================================================+ +| The LZW encoding | ++==========================================================+ + +The LZW scheme is due to three searchers, i.e. Abraham Lempel and Jacob Ziv +worked on it in 1977, and Terry Welch achieved this scheme in 1984. + +LZW is patented in USA. This patent, number 4,558,302, is covered by Unisys +Corporation. You can usually write (without fees) software codecs which use +the LZW scheme but hardware companies can't do so. You may get a limited +licence by writting to: +Welch Licencing Department +Office of the General Counsel +M/S C1SW19 +Unisys corporation +Blue Bell +Pennsylvania, 19424 (USA) + +If you're occidental, you are surely using an LZW encoding every time you are +speaking, especially when you use a dictionary. Let's consider, for example, +the word "Cirrus". As you read a dictionary, you begin with "A", "Aa", and so +on. But a computer has no experience and it must suppose that some words +already exist. That is why with "Cirrus", it supposes that "C", "Ci", "Cir", +"Cirr", "Cirru", and "Cirrus" exist. Of course, being that this is a computer, +all these words are encoded as index numbers. Every time you go forward, you add +a new number associated to the new word. Being that a computer is byte-based +and not alphabetic-based, you have an initial dictionary of 256 letters instead +of our 26 ('A' to 'Z') letters. + +Example: Let's code "XYXYZ". First step, "X" is recognized in the initial +dictionary of 256 letters as the 89th. Second step, "Y" is read. Does "XY" +exist? No, then "XY" is stored as the word 256. You write in the output stream +the ASCII of "X", i.e. 88. Now "YX" is tested as not referenced in the current +dictionary. It is stored as the word 257. You write now in the output stream 89 +(ASCII of "Y"). "XY" is now met. But now "XY" is known as the reference 256. +Being that "XY" exists, you test the sequence with one more letter, i.e. "XYZ". +This last word is not referenced in the current dictionary. You write then the +value 256. Finally, you reach the last letter ("Z"). You add "YZ" as the +reference 258 but it is the last letter. That is why you just write the value +90 (ASCII of "Z"). + +Another encoding sample with the string "ABADABCCCABCEABCECCA". + ++----+-----+---------------+------+----------+-------------------------+------+ +|Step|Input|Dictionary test|Prefix|New symbol|Dictionary |Output| +| | | | | |D0=ASCII with 256 letters| | ++----+-----+---------------+------+----------+-------------------------+------+ +| 1 | "A" |"A" in D0 | "A" | "B" | D1=D0 | 65 | +| | "B" |"AB" not in D0 | | | and "AB"=256 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 2 | "A" |"B" in D1 | "B" | "A" | D2=D1 | 66 | +| | |"BA" not in D1 | | | and "BA"=257 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 3 | "D" |"A" in D2 | "A" | "D" | D3=D2 | 65 | +| | |"AD" not in D2 | | | and "AD"=258 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 4 | "A" |"D" in D3 | "D" | "A" | D4=D3 | 68 | +| | |"DA" not in D3 | | | and "DA"=259 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 5 | "B" |"A" in D4 | "AB" | "C" | D5=D4 | 256 | +| | "C" |"AB" in D4 | | | and "ABC"=260 | | +| | |"ABC" not in D4| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 6 | "C" |"C" in D5 | "C" | "C" | D6=D5 | 67 | +| | |"CC" not in D5 | | | and "CC"=261 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 7 | "C" |"C" in D6 | "CC" | "A" | D7=D6 | 261 | +| | "A" |"CC" in D6 | | | and "CCA"=262 | | +| | |"CCA" not in D6| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 8 | "B" |"A" in D7 | "ABC"| "E" | D8=D7 | 260 | +| | "C" |"AB" in D7 | | | and "ABCE"=263 | | +| | "E" |"ABC" in D7 | | | | | +| | <"ABCE" not in D7| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 9 | "A" |"E" in D8 | "E" | "A" | D9=D8 | 69 | +| | |"EA" not in D8 | | | and "EA"=264 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 10 | "B" |"A" in D9 |"ABCE"| "C" | D10=D9 | 263 | +| | "C" |"AB" in D9 | | | and "ABCEC"=265 | | +| | "E" |"ABC" in D9 | | | | | +| | "C" |"ABCE" in D9 | | | | | +| | <"ABCEC" not in D9> | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 11 | "C" |"C" in D10 | "CCA"| | | 262 | +| | "A" |"CC" in D10 | | | | | +| | <"CCA" not in D10| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ + +You will notice a problem with the above output: How to write a code of 256 +(for example) on 8 bits? It's simple to solve this problem. You just say that +the encoding starts with 9 bits and as you reach the 512th word, you use a +10-bits encoding. With 1024 words, you use 11 bits; with 2048 words, 12 bits; +and so on with all numbers of 2^n (n is positive). To better synchronize +the coder and the decoder with all that, most of implementations use two +additional references. The word 256 is a code of reinitialisation (the codec +must reinitialize completely the current dictionary to its 256 initial letters) +and the word 257 is a code of end of information (no more data to read). +Of course, you start your first new word as the code number 258. + +You can also do so as in the GIF file format and start with an initial +dictionary of 18 words to code an input stream with only letters coded on 4 bits +(you start with codes of 5 bits in the output stream!). The 18 initial words +are: 0 to 15 (initial letters), 16 (reinit the dictionary), and 17 (end of +information). First new word has code 18, second word, code 19, ... + +Important: You can consider that your dictionary is limited to 4096 different +words (as in GIF and TIFF file formats). But if your dictionary is full, you +can decide to send old codes *without* reinitializing the dictionary. All the +decoders must be compliant with this. This enables you to consider that it is +not efficient to reinitialize the full dictionary. Instead of this, you don't +change the dictionary and you send/receive (depending if it's a coder or a +decoder) existing codes in the full dictionary. + +My codecs are able to deal as well with most of initial size of data in the +initial dictionary as with full dictionary. + +Let's see how to decode an LZW encoding. We saw with true dynamical Huffman +scheme that you needed an header in the encoding codes. Any header is useless +in LZW scheme. When two successive bytes are read, the first must exist in the +dictionary. This code can be immediately decoded and written in the output +stream. If the second code is equal or less than the word number in the current +dictionary, this code is decoded as the first one. At the opposite, if the +second code is equal to the word number in dictionary plus one, this means you +have to write a word composed with the word (the sentence, not the code number) +of the last code plus the first character of the last code. In between, you make +appear a new word. This new word is the one you just sent to the output stream, +it means composed by all the letters of the word associated to the first code +and the first letter of the word of the second code. You continue the processing +with the second and third codes read in the input stream (of codes)... + +Example: Let's decode the previous encoding given a bit more above. + ++------+-------+----------------+----------+------------------+--------+ +| Step | Input | Code to decode | New code | Dictionary | Output | ++------+-------+----------------+----------+------------------+--------+ +| 1 | 65 | 65 | 66 | 65,66=256 | "A" | +| | 66 | | | | | ++------+-------+----------------+----------+------------------+--------+ +| 2 | 65 | 66 | 65 | 66,65=257 | "B" | ++------+-------+----------------+----------+------------------+--------+ +| 3 | 68 | 65 | 68 | 65,68=258 | "A" | ++------+-------+----------------+----------+------------------+--------+ +| 4 | 256 | 68 | 256 | 68,65=259 | "D" | ++------+-------+----------------+----------+------------------+--------+ +| 5 | 67 | 256 | 67 | 65,66,67=260 | "AB" | ++------+-------+----------------+----------+------------------+--------+ +| 6 | 261 | 67 | 261 | 67,67=261 | "C" | ++------+-------+----------------+----------+------------------+--------+ +| 7 | 260 | 261 | 260 | 67,67,65=262 | "CC" | ++------+-------+----------------+----------+------------------+--------+ +| 8 | 69 | 260 | 69 | 65,66,67,69=263 | "ABC" | ++------+-------+----------------+----------+------------------+--------+ +| 9 | 263 | 69 | 263 | 69,65=264 | "E" | ++------+-------+----------------+----------+------------------+--------+ +| 10 | 262 | 263 | 262 |65,66,67,69,67=256| "ABCE" | ++------+-------+----------------+----------+------------------+--------+ +| 11 | | 262 | | | "CCA" | ++------+-------+----------------+----------+------------------+--------+ + +Summary: The step 4 is an explicit example. The code to decode is 68 ("D" in +ASCII) and the new code is 256. The new word to add to the dictionary is the +letters of the first word plus the the first letter of the second code (code +256), i.e. 65 ("A" in ASCII) plus 68 ("D"). So the new word has the letters 68 +and 65 ("AD"). + +The step 6 is quite special. The first code to decode is referenced but the +second new code is not referenced being that the dictionary is limited to 260 +referenced words. We have to make it as the second previously given case, it +means you must take the word to decode plus its first letter, i.e. "C"+"C"="CC". +Be care, if any encountered code is *upper* than the dictionary size plus 1, it +means you have a problem in your data and/or your codecs are...bad! + +Tricks to improve LZW encoding (but it becomes a non-standard encoding): +- To limit the dictionary to an high amount of words (4096 words maximum enable +you to encode a stream of a maximmum 7,370,880 letters with the same dictionary) +- To use a dictionary of less than 258 if possible (example, with 16 color +pictures, you start with a dictionary of 18 words) +- To not reinitialize a dictionary when it is full +- To reinitialize a dictionary with the most frequent of the previous dictionary +- To use the codes from (current dictionary size+1) to (maximum dictionary size) +because these codes are not used in the standard LZW scheme. +Such a compression scheme has been used (successfully) by Robin Watts +. + ++==========================================================+ +| Summary | ++==========================================================+ + +------------------------------------------------- +RLE type 1: +Fastest compression. Good ratio for general purpose. +Doesn't need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 2: +Fast compression. Very good ratio in general (even for general purposes). +Need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 3: +Slowest compression. Good ratio on image file,quite middle for general purposes. +Need to read the data by twice. +Change line: +#define MAX_RASTER_SIZE 256 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +RLE type 4: +Slow compression. Good ratio on image file, middle in general purposes. +Change line: +#define MAX_RASTER_SIZE 66 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +Huffman: +Fast compression. Good ratio on text files and similar, middle for general +purposes. Interesting method to use to compress a buffer already compressed by +RLE types 1 or 2 methods... +Decoding fast. +------------------------------------------------- +LZW: +Quite fast compression. Good, see even very good ratio, for general purposes. +Bigger the data are, better the compression ratio is. +Decoding quite fast. +------------------------------------------------- + +The source codes work on all kinds of computers with a C compiler. +With the compiler, optimize the speed run option instead of space option. +With UNIX system, it's better to compile them with option -O. +If you don't use a GNU compiler, the source file MUST NOT have a size +over 4 Gb for RLE 2, 3, and Huffman, because I count the number +of occurrences of the bytes. +So, with GNU compilers, 'unsigned lont int' is 8 bytes instead of 4 bytes +(as normal C UNIX compilers and PCs' compilers, such as Microsoft C++ +and Borland C++). +Actually: +* Normal UNIX compilers, => 4 Gb (unsigned long int = 4 bytes) + Microsoft C++ and Borland C++ for PCs +* GNU UNIX compilers => 17179869184 Gb (unsigned long int = 8 bytes) + ++==========================================================+ +| END | ++==========================================================+ diff --git a/all_pairs/source/huff_enc/huff_enc.c b/all_pairs/source/huff_enc/huff_enc.c new file mode 100644 index 0000000..2e739e6 --- /dev/null +++ b/all_pairs/source/huff_enc/huff_enc.c @@ -0,0 +1,589 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: huff_enc + + Author: David Bourgin (David.Bourgin@ufrima.imag.fr) + + Function: Example of Huffman encoding + + Source: ftp://turing.imag.fr/pub/compression/ (1994-09-22) + + Original name: codhuff.c + + Changes: I/O to char arrays instead of file i/o. + Dynamic memory allocation replaced by array. + Explicit sorting algorithm. + + License: + +The source code files (codrl1.c, dcodrl1.c, codrle2.c, dcodrle2.c, codrle3.c, +dcodrle3.c, codrle4.c, dcodrle4.c, codhuff.c, dcodhuff.c) are copyrighted. +They have been uploaded on ftp in turing.imag.fr (129.88.31.7):/pub/compression +on 22/5/94 and have been modified on 22/9/94. +(c) David Bourgin - 1994 +The source codes I provide have no buggs (!) but being that I make them +available for free I have some notes to make. They can change at any time +without notice. I assume no responsability or liability for any errors or +inaccurracies, make no warranty of any kind (express, implied or statutory) +with respect to this publication and expressly disclaim any and all warranties +of merchantability, fitness for particular purposes. Of course, if you have +some problems to use the information presented here, I will try to help you if +I can. + +If you include the source codes in your application, here are the conditions: +- You have to put my name in the header of your source file (not in the +excutable program if you don't want) (this item is a must) +- I would like to see your resulting application, if possible (this item is not +a must, because some applications must remain secret) +- Whenever you gain money with your application, I would like to receive a very +little part in order to be encouraged to update my source codes and to develop +new schemes (this item is not a must) + +*/ + + +/* + Declaration of types +*/ + + +#include "../extra.h" +typedef struct huff_enc_s_tree { + unsigned int byte; /* A byte has to be coded as an unsigned integer to + allow a node to have a value over 255 */ + unsigned long int weight; + struct huff_enc_s_tree *left_ptr; + struct huff_enc_s_tree *right_ptr; +} huff_enc_t_tree; + +typedef struct { + unsigned char bits[32]; + unsigned int bits_nb; +} huff_enc_t_bin_val; + + +/* + Forward declaration of functions +*/ + +void huff_enc_init( void ); +int huff_enc_return( void ); +void huff_enc_beginning_of_data(); +int huff_enc_end_of_data(); +int huff_enc_read_byte(); +void huff_enc_write_byte( char ch ); +void huff_enc_write_bin_val( huff_enc_t_bin_val bin_val ); +void huff_enc_fill_encoding( void ); +void huff_enc_write_header( huff_enc_t_bin_val codes_table[257] ); +int huff_enc_weighhuff_enc_t_tree_comp( const void *t1, const void *t2 ); +void huff_enc_swapi( char *ii, char *ij, unsigned long es ); +char *huff_enc_pivot( char *a, unsigned long n, unsigned long es ); +void huff_enc_qsort( char *a, unsigned long n, unsigned long es ); +huff_enc_t_tree *huff_enc_build_tree_encoding( huff_enc_t_tree heap[514] ); +void huff_enc_encode_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257], huff_enc_t_bin_val *code_val ); +void huff_enc_create_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257] ); +void huff_enc_main(); +//int main( void ); + + +/* + Declaration of global variables +*/ + +static int huff_enc_input_pos; +static int huff_enc_output_pos; +static unsigned char huff_enc_output[1024]; +static unsigned char huff_enc_byte_nb_to_write = 0; +static unsigned char huff_enc_val_to_write = 0; + + +/* + Initialization- and return-value-related functions +*/ + +#define huff_enc_plaintext_len 600 +static const char *huff_enc_plaintext = + "You are doubtless asking \"How can I reduce the data size without losing " + "some informations?\". It's easy to answer to this question. I'll only take " + "an example. I'm sure you have heard about the morse. This system established " + "in the 19th century use a scheme very close to the huffman one. In the morse " + "you encode the letters to transmit with two kinds of signs. If you encode " + "these two sign possibilities in one bit, the symbol 'e' is transmitted in a " + "single bit and the symbols 'y' and 'z' need four bits. Look at the symbols " + "in the text you are reading, you'll fast understand the compression ratio..."; + +#define huff_enc_encoded_len 419 +static unsigned char huff_enc_encoded[huff_enc_encoded_len] = { + 128, 0, 0, 0, 80, 133, 32, 32, 128, 100, 4, 32, 63, 239, 255, 240, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 7, 167, 21, 129, 232, 69, 120, 132, 217, 20, 162, 19, 164, 39, 133, + 252, 138, 105, 20, 194, 19, 129, 240, 172, 138, 248, 150, 11, 11, 240, 201, + 68, 64, 114, 53, 17, 42, 37, 195, 128, 212, 116, 194, 41, 98, 52, 51, + 12, 132, 112, 244, 3, 36, 33, 52, 39, 135, 164, 33, 62, 156, 87, 14, + 110, 22, 87, 50, 85, 198, 99, 142, 140, 194, 81, 78, 158, 84, 129, 254, + 129, 248, 110, 179, 159, 192, 145, 133, 184, 184, 28, 210, 96, 146, 73, 10, + 226, 21, 83, 152, 74, 13, 111, 132, 199, 202, 219, 241, 74, 193, 167, 105, + 222, 31, 147, 6, 55, 31, 129, 40, 232, 52, 153, 160, 148, 18, 36, 197, + 45, 216, 202, 86, 30, 31, 177, 90, 133, 138, 248, 23, 81, 195, 160, 100, + 215, 93, 50, 185, 225, 251, 23, 6, 230, 225, 229, 112, 71, 80, 96, 141, + 205, 176, 230, 85, 196, 9, 24, 93, 90, 121, 225, 76, 68, 152, 63, 25, + 107, 140, 101, 204, 214, 77, 26, 194, 96, 18, 48, 77, 210, 137, 1, 253, + 4, 230, 248, 56, 240, 224, 111, 163, 95, 10, 12, 223, 7, 234, 167, 129, + 40, 36, 96, 135, 125, 245, 250, 2, 198, 120, 127, 0, 145, 133, 213, 167, + 135, 149, 195, 67, 235, 108, 9, 24, 87, 17, 102, 152, 37, 4, 222, 131, + 188, 144, 73, 36, 128, 73, 20, 81, 152, 177, 133, 248, 28, 165, 131, 120, + 127, 240, 242, 184, 104, 125, 109, 129, 35, 30, 4, 145, 65, 202, 88, 9, + 138, 103, 44, 205, 100, 167, 24, 152, 11, 24, 51, 37, 66, 9, 24, 31, + 174, 202, 212, 49, 152, 18, 96, 155, 208, 119, 146, 45, 97, 48, 56, 28, + 194, 90, 224, 204, 144, 232, 176, 36, 96, 126, 187, 43, 83, 12, 121, 129, + 209, 96, 197, 35, 2, 54, 176, 249, 92, 208, 204, 145, 188, 41, 170, 180, + 71, 16, 36, 96, 126, 187, 43, 83, 19, 0, 145, 129, 100, 209, 15, 43, + 135, 55, 6, 238, 180, 194, 90, 17, 229, 115, 21, 168, 251, 140, 131, 162, + 217, 166, 93, 22, 4, 140, 31, 91, 166, 55, 25, 202, 192, 111, 20, 171, + 207, 39, 192, +}; + + +void huff_enc_init( void ) +{ + huff_enc_input_pos = 0; + huff_enc_output_pos = 0; +} + + +int huff_enc_return( void ) +{ + int i; + _Pragma( "loopbound min 1 max 419" ) + for ( i = 0; i < huff_enc_encoded_len; i++ ) { + if ( huff_enc_encoded[i] != huff_enc_output[i] ) return i + 1; + } + return 0; +} + + +/* + Input / output functions +*/ + +void huff_enc_beginning_of_data() +{ + huff_enc_input_pos = 0; +} + + +int huff_enc_end_of_data() +{ + return huff_enc_input_pos >= huff_enc_plaintext_len; +} + + +int huff_enc_read_byte() +{ + return huff_enc_plaintext[huff_enc_input_pos++]; +} + + +void huff_enc_write_byte( char ch ) +{ + huff_enc_output[huff_enc_output_pos++] = ch; +} + + +void huff_enc_write_bin_val( huff_enc_t_bin_val bin_val ) +/* Returned parameters: None + Action: Writes in the output stream the value binary-coded into 'bin_val' + Errors: An input/output error could disturb the running of the program +*/ +{ + unsigned char bit_indice; + unsigned char bin_pos = ( bin_val.bits_nb - 1 ) & 7; + unsigned int pos_byte = ( bin_val.bits_nb - 1 ) >> 3; + + for ( bit_indice = 1; + bit_indice <= bin_val.bits_nb; + bit_indice++ ) { + /* Watch for the current bit to write */ + huff_enc_val_to_write = ( huff_enc_val_to_write << 1 ) | + ( ( bin_val.bits[pos_byte] >> bin_pos ) & 1 ); + /* Move to the next bit to write */ + if ( !bin_pos ) { + pos_byte--; + bin_pos = 7; + } else bin_pos--; + if ( huff_enc_byte_nb_to_write == 7 ) { + /* Are already 8 bits written? */ + huff_enc_write_byte( huff_enc_val_to_write ); + huff_enc_byte_nb_to_write = 0; + huff_enc_val_to_write = 0; + } else /* No, then the next writting will be in the next bit */ + huff_enc_byte_nb_to_write++; + } +} + + +void huff_enc_fill_encoding( void ) +/* Returned parameters: None + Action: Fills the last byte to write in the output stream with zero values + Errors: An input/output error could disturb the running of the program +*/ +{ + if ( huff_enc_byte_nb_to_write ) + huff_enc_write_byte( huff_enc_val_to_write << + ( 8 - huff_enc_byte_nb_to_write ) ); +} + + +void huff_enc_write_header( huff_enc_t_bin_val codes_table[257] ) +/* Returned parameters: None + Action: Writes the header in the stream of codes + Errors: An input/output error could disturb the running of the program +*/ +{ + unsigned int i, j; + huff_enc_t_bin_val bin_val_to_0; + huff_enc_t_bin_val bin_val_to_1; + huff_enc_t_bin_val bin_val; + /* Is used to send in binary mode via huff_enc_write_bin_val */ + + *bin_val_to_0.bits = 0; + bin_val_to_0.bits_nb = 1; + *bin_val_to_1.bits = 1; + bin_val_to_1.bits_nb = 1; + for ( i = 0, j = 0; j <= 255; j++ ) + if ( codes_table[j].bits_nb ) i++; + /* From there, i contains the number of bytes of the several + non 0 occurrences to encode. + First part of the header: Specifies the bytes that appear + in the source of encoding */ + if ( i < 32 ) { + /* Encoding of the appeared bytes with a block of bytes */ + huff_enc_write_bin_val( bin_val_to_0 ); + bin_val.bits_nb = 5; + *bin_val.bits = ( unsigned char )( i - 1 ); + huff_enc_write_bin_val( bin_val ); + bin_val.bits_nb = 8; + for ( j = 0; j <= 255; j++ ) + if ( codes_table[j].bits_nb ) { + *bin_val.bits = ( unsigned char )j; + huff_enc_write_bin_val( bin_val ); + } + } else { + /* Encoding of the appeared bytes with a block of bits */ + huff_enc_write_bin_val( bin_val_to_1 ); + for ( j = 0; j <= 255; j++ ) + if ( codes_table[j].bits_nb ) + huff_enc_write_bin_val( bin_val_to_1 ); + else huff_enc_write_bin_val( bin_val_to_0 ); + }; + /* Second part of the header: Specifies the encoding of the bytes + (fictive or not) that appear in the source of encoding */ + for ( i = 0; i <= 256; i++ ) + if ( ( j = codes_table[i].bits_nb ) != 0 ) { + if ( j < 33 ) { + huff_enc_write_bin_val( bin_val_to_0 ); + bin_val.bits_nb = 5; + } else { + huff_enc_write_bin_val( bin_val_to_1 ); + bin_val.bits_nb = 8; + } + *bin_val.bits = ( unsigned char )( j - 1 ); + huff_enc_write_bin_val( bin_val ); + huff_enc_write_bin_val( codes_table[i] ); + } +} + + +int huff_enc_weighhuff_enc_t_tree_comp( const void *t1, const void *t2 ) +/* Returned parameters: Returns a comparison status + Action: Returns a negative, zero or positive integer depending on the weight + of 'tree2' is less than, equal to, or greater than the weight of + 'tree1' + Errors: None +*/ +{ + huff_enc_t_tree *const *tree1 = ( huff_enc_t_tree *const * ) t1; + huff_enc_t_tree *const *tree2 = ( huff_enc_t_tree *const * ) t2; + return ( ( *tree2 )->weight ^ ( *tree1 )->weight ) + ? ( ( ( *tree2 )->weight < ( *tree1 )->weight ) ? -1 : 1 ) : 0; +} + + +void huff_enc_swapi( char *ii, char *ij, unsigned long es ) +{ + char *i, *j, c; + + i = ( char * )ii; + j = ( char * )ij; + _Pragma( "loopbound min 4 max 4" ) + do { + c = *i; + *i++ = *j; + *j++ = c; + es -= sizeof( char ); + } while ( es != 0 ); +} + + +char *huff_enc_pivot( char *a, unsigned long n, unsigned long es ) +{ + long j; + char *pi, *pj, *pk; + + j = n / 6 * es; + pi = a + j; /* 1/6 */ + j += j; + pj = pi + j; /* 1/2 */ + pk = pj + j; /* 5/6 */ + if ( huff_enc_weighhuff_enc_t_tree_comp( pi, pj ) < 0 ) { + if ( huff_enc_weighhuff_enc_t_tree_comp( pi, pk ) < 0 ) { + if ( huff_enc_weighhuff_enc_t_tree_comp( pj, pk ) < 0 ) + return pj; + return pk; + } + return pi; + } + if ( huff_enc_weighhuff_enc_t_tree_comp( pj, pk ) < 0 ) { + if ( huff_enc_weighhuff_enc_t_tree_comp( pi, pk ) < 0 ) + return pi; + return pk; + } + return pj; +} + + +void huff_enc_qsort( char *a, unsigned long n, unsigned long es ) +{ + unsigned long j; + char *pi, *pj, *pn; + unsigned int flowfactdummy = 0; + + _Pragma( "loopbound min 0 max 8" ) + while ( n > 1 ) { + if ( n > 10 ) { + pi = huff_enc_pivot( a, n, es ); + } else { + pi = a + ( n >> 1 ) * es; + } + + huff_enc_swapi( a, pi, es ); + pi = a; + pn = a + n * es; + pj = pn; + _Pragma( "loopbound min 1 max 110" ) + while ( 1 ) { + /* wcc note: this assignment expression was added to avoid assignment of + * multiple loop bound annotations to same loop (cf. Ticket #0002323). */ + flowfactdummy++; + _Pragma( "loopbound min 1 max 19" ) + do { + pi += es; + } while ( pi < pn && huff_enc_weighhuff_enc_t_tree_comp( pi, a ) < 0 ); + _Pragma( "loopbound min 1 max 25" ) + do { + pj -= es; + } while ( pj > a && huff_enc_weighhuff_enc_t_tree_comp( pj, a ) > 0 ); + if ( pj < pi ) + break; + huff_enc_swapi( pi, pj, es ); + } + huff_enc_swapi( a, pj, es ); + j = ( pj - a ) / es; + + n = n - j - 1; + if ( j >= n ) { + huff_enc_qsort( a, j, es ); + a += ( j + 1 ) * es; + } else { + huff_enc_qsort( a + ( j + 1 )*es, n, es ); + n = j; + } + } +} + + +huff_enc_t_tree *huff_enc_build_tree_encoding( huff_enc_t_tree heap[514] ) +/* Returned parameters: Returns a tree of encoding + Action: Generates an Huffman encoding tree based on the data from + the stream to compress + Errors: None +*/ +{ + unsigned int i; + unsigned int heap_top = 0; + huff_enc_t_tree *occurrences_table[257]; + huff_enc_t_tree *ptr_fictive_tree; + + /* Sets up the occurrences number of all bytes to 0 */ + for ( i = 0; i <= 256; i++ ) { + occurrences_table[i] = &heap[heap_top++]; + occurrences_table[i]->byte = i; + occurrences_table[i]->weight = 0; + occurrences_table[i]->left_ptr = 0; + occurrences_table[i]->right_ptr = 0; + } + /* Valids the occurrences of 'occurrences_table' with regard to the data to + compress */ + if ( !huff_enc_end_of_data() ) { + while ( !huff_enc_end_of_data() ) { + i = huff_enc_read_byte(); + occurrences_table[i]->weight++; + } + occurrences_table[256]->weight = 1; + + /* Sorts the occurrences table depending on the weight of each character */ + huff_enc_qsort( ( char * )occurrences_table, 257, sizeof( huff_enc_t_tree * ) ); + + for ( i = 256; ( i != 0 ) && ( !occurrences_table[i]->weight ); i-- ) + ; + i++; + /* From there, 'i' gives the number of different bytes with a 0 occurrence + in the stream to compress */ + while ( i > 0 ) { + /* Looks up (i+1)/2 times the occurrence table to link the nodes in an + unique tree */ + ptr_fictive_tree = &heap[heap_top++]; + ptr_fictive_tree->byte = 257; + ptr_fictive_tree->weight = occurrences_table[--i]->weight; + ptr_fictive_tree->left_ptr = occurrences_table[i]; + if ( i ) { + i--; + ptr_fictive_tree->weight += occurrences_table[i]->weight; + ptr_fictive_tree->right_ptr = occurrences_table[i]; + } else ptr_fictive_tree->right_ptr = 0; + occurrences_table[i] = ptr_fictive_tree; + + //qsort( ( char * )occurrences_table, i + 1, sizeof( *huff_enc_t_tree ), + //huff_enc_weighhuff_enc_t_tree_comp ); + huff_enc_qsort( ( char * )occurrences_table, i + 1, + sizeof( huff_enc_t_tree * ) ); + + if ( i ) /* Is there an other node in the occurrence tables? */ + i++; /* Yes, then takes care to the fictive node */ + } + } + return ( *occurrences_table ); +} + + +void huff_enc_encode_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257], + huff_enc_t_bin_val *code_val ) +/* Returned parameters: The data of 'codes_table' can have been modified + Action: Stores the encoding tree as a binary encoding table to speed up the + access. 'val_code' gives the encoding for the current node of the tree + Errors: None +*/ +{ + unsigned int i; + huff_enc_t_bin_val tmp_code_val; + + if ( tree->byte == 257 ) { + if ( tree->left_ptr != 0 ) + /* The sub-trees on left begin with an bit set to 1 */ + { + tmp_code_val = *code_val; + for ( i = 31; i > 0; i-- ) + code_val->bits[i] = ( code_val->bits[i] << 1 ) | + ( code_val->bits[i - 1] >> 7 ); + *code_val->bits = ( *code_val->bits << 1 ) | 1; + code_val->bits_nb++; + huff_enc_encode_codes_table( tree->left_ptr, codes_table, code_val ); + *code_val = tmp_code_val; + }; + if ( tree->right_ptr != 0 ) + /* The sub-trees on right begin with an bit set to 0 */ + { + tmp_code_val = *code_val; + for ( i = 31; i > 0; i-- ) + code_val->bits[i] = ( code_val->bits[i] << 1 ) | + ( code_val->bits[i - 1] >> 7 ); + *code_val->bits <<= 1; + code_val->bits_nb++; + huff_enc_encode_codes_table( tree->right_ptr, codes_table, code_val ); + *code_val = tmp_code_val; + }; + } else codes_table[tree->byte] = *code_val; +} + + +void huff_enc_create_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257] ) +/* Returned parameters: The data in 'codes_table' will be modified + Action: Stores the encoding tree as a binary encoding table to speed up + the access by calling encode_codes_table + Errors: None +*/ +{ + unsigned int i, j; + huff_enc_t_bin_val code_val; + + _Pragma( "loopbound min 32 max 32" ) + for ( i = 0; i < 32; i++ ) { + code_val.bits[i] = 0; + } + code_val.bits_nb = 0; + _Pragma( "loopbound min 257 max 257" ) + for ( j = 0; j < 257; j++ ) { + _Pragma( "loopbound min 32 max 32" ) + for ( i = 0; i < 32; i++ ) { + codes_table[j].bits[i] = 0; + } + codes_table[j].bits_nb = 0; + } + _Pragma( "marker call_encode" ) + _Pragma( "flowrestriction 1*huff_enc_encode_codes_table <= 77*call_encode" ) + huff_enc_encode_codes_table( tree, codes_table, &code_val ); +} + + +void _Pragma( "entrypoint" ) huff_enc_main() +/* Returned parameters: None + Action: Compresses with Huffman method all bytes read by the function + 'huff_enc_read_byte' + Errors: None +*/ +{ + huff_enc_t_tree *tree; + huff_enc_t_tree heap[514]; + huff_enc_t_bin_val encoding_table[257]; + unsigned char byte_read; + + if ( !huff_enc_end_of_data() ) { + /* Generates only whether there are data */ + tree = huff_enc_build_tree_encoding( heap ); + /* Creation of the best adapted tree */ + huff_enc_create_codes_table( tree, encoding_table ); + /* Obtains the binary encoding in an array to speed up the accesses */ + huff_enc_write_header( encoding_table ); + /* Writes the defintion of the encoding */ + huff_enc_beginning_of_data(); /* Real compression of the data */ + while ( !huff_enc_end_of_data() ) { + byte_read = huff_enc_read_byte(); + huff_enc_write_bin_val( encoding_table[byte_read] ); + } + huff_enc_write_bin_val( encoding_table[256] ); + /* Code of the end of encoding */ + huff_enc_fill_encoding(); + /* Fills the last byte before closing file, if any */ + } +} + + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete + mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD + MV[][][]: motion vectors (frame format) + mv_field_sel: top/bottom field (for field prediction) + motion_type: MC_FRAME, MC_FIELD + + uses global vars: mpeg2_pict_type, frame_pred_dct +*/ +void mpeg2_motion_estimation( unsigned char *oldorg, unsigned char *neworg, + unsigned char *oldref, unsigned char *newref, + unsigned char *cur, unsigned char *curref, + int sxf, int syf, int sxb, int syb, + struct mbinfo *mbi, int secondfield, int ipflag ) +{ + int i, j; + + + /* loop through all macroblocks of the picture */ + _Pragma( "loopbound min 16 max 16" ) + for ( j = 0; j < mpeg2_height2; j += 16 ) { + i = 0; + _Pragma( "loopbound min 22 max 22" ) + for ( ; i < mpeg2_width; i += 16 ) { + if ( mpeg2_pict_struct == 3 ) + mpeg2_frame_ME( + oldorg, neworg, oldref, newref, cur, i, j, sxf, syf, sxb, syb, mbi ); + else + mpeg2_field_ME( + oldorg, neworg, oldref, newref, cur, curref, i, j, sxf, syf, sxb, syb, + mbi, secondfield, ipflag ); + mbi++; + } + } +} + + +void mpeg2_frame_ME( unsigned char *oldorg, unsigned char *neworg, + unsigned char *oldref, unsigned char *newref, + unsigned char *cur, int i, int j, int sxf, int syf, + int sxb, int syb, struct mbinfo *mbi ) +{ + int imin, jmin, iminf, jminf, iminr, jminr; + int imint, jmint, iminb, jminb; + int imintf, jmintf, iminbf, jminbf; + int imintr, jmintr, iminbr, jminbr; + int var, v0; + int dmc, dmcf, dmcr, dmci, vmc, vmcf, vmcr, vmci; + int dmcfield, dmcfieldf, dmcfieldr, dmcfieldi; + int tsel, bsel, tself, bself, tselr, bselr; + unsigned char *mb; + int imins[ 2 ][ 2 ], jmins[ 2 ][ 2 ]; + int imindp, jmindp, imindmv, jmindmv, dmc_dp, vmc_dp; + + + mb = cur + i + mpeg2_width * j; + + var = mpeg2_variance( mb, mpeg2_width ); + + if ( mpeg2_pict_type == 1 ) + mbi->mb_type = 1; + else + + if ( mpeg2_pict_type == 2 ) { + if ( mpeg2_frame_pred_dct ) { + dmc = + mpeg2_fullsearch( + oldorg, oldref, mb, mpeg2_width, i, j, sxf, syf, 16, mpeg2_width, + mpeg2_height, &imin, &jmin ); + vmc = + mpeg2_dist2( + oldref + ( imin >> 1 ) + mpeg2_width * ( jmin >> 1 ), mb, mpeg2_width, + imin & 1, jmin & 1, 16 ); + mbi->motion_type = 2; + } else { + mpeg2_frame_estimate( + oldorg, oldref, mb, i, j, sxf, syf, &imin, &jmin, &imint, &jmint, + &iminb, &jminb, &dmc, &dmcfield, &tsel, &bsel, imins, jmins ); + + if ( mpeg2_M == 1 ) + mpeg2_dpframe_estimate( + oldref, mb, i, j >> 1, imins, jmins, &imindp, &jmindp, &imindmv, + &jmindmv, &dmc_dp, &vmc_dp ); + + /* select between dual prime, frame and field prediction */ + if ( ( mpeg2_M == 1 ) && ( dmc_dp < dmc ) && ( dmc_dp < dmcfield ) ) { + mbi->motion_type = 3; + dmc = dmc_dp; + vmc = vmc_dp; + } else + + if ( dmc <= dmcfield ) { + mbi->motion_type = 2; + vmc = + mpeg2_dist2( + oldref + ( imin >> 1 ) + mpeg2_width * ( jmin >> 1 ), mb, + mpeg2_width, imin & 1, jmin & 1, 16 ); + } else { + mbi->motion_type = 1; + dmc = dmcfield; + vmc = + mpeg2_dist2( + oldref + ( tsel ? mpeg2_width : 0 ) + ( imint >> 1 ) + + ( mpeg2_width << 1 ) * ( jmint >> 1 ), + mb, mpeg2_width << 1, imint & 1, jmint & 1, 8 ); + vmc += + mpeg2_dist2( + oldref + ( bsel ? mpeg2_width : 0 ) + ( iminb >> 1 ) + + ( mpeg2_width << 1 ) * ( jminb >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminb & 1, jminb & 1, 8 ); + } + } + + /* + select between intra or non-intra coding: + + selection is based on intra block variance (var) vs. + prediction error variance (vmc) + + blocks with small prediction error are always coded non-intra + even if variance is smaller (is this reasonable?) + */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + /* + select between MC / No-MC + + use No-MC if var(No-MC) <= 1.25*var(MC) + (i.e slightly biased towards No-MC) + + blocks with small prediction error are always coded as No-MC + (requires no motion vectors, allows skipping) + */ + v0 = + mpeg2_dist2( oldref + i + mpeg2_width * j, mb, mpeg2_width, 0, 0, 16 ); + + if ( ( 4 * v0 > 5 * vmc ) && ( v0 >= 9 * 256 ) ) { + /* use MC */ + var = vmc; + mbi->mb_type = 8; + + if ( mbi->motion_type == 2 ) { + mbi->MV[ 0 ][ 0 ][ 0 ] = imin - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin - ( j << 1 ); + } else + + if ( mbi->motion_type == 3 ) { + /* these are FRAME vectors */ + /* same parity vector */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imindp - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = ( jmindp << 1 ) - ( j << 1 ); + + /* opposite parity vector */ + mbi->dmvector[ 0 ] = imindmv; + mbi->dmvector[ 1 ] = jmindmv; + } else { + /* these are FRAME vectors */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imint - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = ( jmint << 1 ) - ( j << 1 ); + mbi->MV[ 1 ][ 0 ][ 0 ] = iminb - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = ( jminb << 1 ) - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = tsel; + mbi->mv_field_sel[ 1 ][ 0 ] = bsel; + } + } else { + /* No-MC */ + var = v0; + mbi->mb_type = 0; + mbi->motion_type = 2; + mbi->MV[ 0 ][ 0 ][ 0 ] = 0; + mbi->MV[ 0 ][ 0 ][ 1 ] = 0; + } + } + } else { /* if (mpeg2_pict_type==B_TYPE) */ + + if ( mpeg2_frame_pred_dct ) { + /* forward */ + dmcf = + mpeg2_fullsearch( + oldorg, oldref, mb, mpeg2_width, i, j, sxf, syf, 16, mpeg2_width, + mpeg2_height, &iminf, &jminf ); + vmcf = + mpeg2_dist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), mb, + mpeg2_width, iminf & 1, jminf & 1, 16 ); + + /* backward */ + dmcr = + mpeg2_fullsearch( + neworg, newref, mb, mpeg2_width, i, j, sxb, syb, 16, mpeg2_width, + mpeg2_height, &iminr, &jminr ); + vmcr = + mpeg2_dist2( + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), mb, + mpeg2_width, iminr & 1, jminr & 1, 16 ); + + /* interpolated (bidirectional) */ + vmci = + mpeg2_bdist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), + mb, mpeg2_width, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + + /* decisions */ + + /* + select between forward/backward/interpolated prediction: + use the one with smallest mean sqaured prediction error + */ + if ( ( vmcf <= vmcr ) && ( vmcf <= vmci ) ) { + vmc = vmcf; + mbi->mb_type = 8; + } else + + if ( vmcr <= vmci ) { + vmc = vmcr; + mbi->mb_type = 4; + } else { + vmc = vmci; + mbi->mb_type = 8 | 4; + } + + mbi->motion_type = 2; + } else { + /* forward prediction */ + mpeg2_frame_estimate( + oldorg, oldref, mb, i, j, sxf, syf, &iminf, &jminf, &imintf, &jmintf, + &iminbf, &jminbf, &dmcf, &dmcfieldf, &tself, &bself, imins, jmins ); + + /* backward prediction */ + mpeg2_frame_estimate( + neworg, newref, mb, i, j, sxb, syb, &iminr, &jminr, &imintr, &jmintr, + &iminbr, &jminbr, &dmcr, &dmcfieldr, &tselr, &bselr, imins, jmins ); + + /* calculate interpolated distance */ + /* frame */ + dmci = + mpeg2_bdist1( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), + mb, mpeg2_width, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + + /* top field */ + dmcfieldi = + mpeg2_bdist1( + oldref + ( imintf >> 1 ) + ( tself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintf >> 1 ), + newref + ( imintr >> 1 ) + ( tselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintr >> 1 ), + mb, mpeg2_width << 1, imintf & 1, jmintf & 1, imintr & 1, jmintr & 1, + 8 ); + + /* bottom field */ + dmcfieldi += + mpeg2_bdist1( + oldref + ( iminbf >> 1 ) + ( bself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbf >> 1 ), + newref + ( iminbr >> 1 ) + ( bselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbr >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbf & 1, jminbf & 1, iminbr & 1, + jminbr & 1, 8 ); + + /* + select prediction type of minimum distance from the + six candidates (field/frame * forward/backward/interpolated) + */ + if ( ( dmci < dmcfieldi ) && ( dmci < dmcf ) && ( dmci < dmcfieldf ) && + ( dmci < dmcr ) && ( dmci < dmcfieldr ) ) { + /* frame, interpolated */ + mbi->mb_type = 8 | 4; + mbi->motion_type = 2; + vmc = + mpeg2_bdist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), + mb, mpeg2_width, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + } else + + if ( ( dmcfieldi < dmcf ) && ( dmcfieldi < dmcfieldf ) && + ( dmcfieldi < dmcr ) && ( dmcfieldi < dmcfieldr ) ) { + /* field, interpolated */ + mbi->mb_type = 8 | 4; + mbi->motion_type = 1; + vmc = + mpeg2_bdist2( + oldref + ( imintf >> 1 ) + ( tself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintf >> 1 ), + newref + ( imintr >> 1 ) + ( tselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintr >> 1 ), + mb, mpeg2_width << 1, imintf & 1, jmintf & 1, imintr & 1, jmintr & 1, + 8 ); + vmc += + mpeg2_bdist2( + oldref + ( iminbf >> 1 ) + ( bself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbf >> 1 ), + newref + ( iminbr >> 1 ) + ( bselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbr >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbf & 1, jminbf & 1, + iminbr & 1, jminbr & 1, 8 ); + } else + + if ( ( dmcf < dmcfieldf ) && ( dmcf < dmcr ) && ( dmcf < dmcfieldr ) ) { + /* frame, forward */ + mbi->mb_type = 8; + mbi->motion_type = 2; + vmc = + mpeg2_dist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), mb, + mpeg2_width, iminf & 1, jminf & 1, 16 ); + } else + + if ( ( dmcfieldf < dmcr ) && ( dmcfieldf < dmcfieldr ) ) { + /* field, forward */ + mbi->mb_type = 8; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + oldref + ( tself ? mpeg2_width : 0 ) + ( imintf >> 1 ) + + ( mpeg2_width << 1 ) * ( jmintf >> 1 ), + mb, mpeg2_width << 1, imintf & 1, jmintf & 1, 8 ); + vmc += + mpeg2_dist2( + oldref + ( bself ? mpeg2_width : 0 ) + ( iminbf >> 1 ) + + ( mpeg2_width << 1 ) * ( jminbf >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbf & 1, jminbf & 1, 8 ); + } else + + if ( dmcr < dmcfieldr ) { + /* frame, backward */ + mbi->mb_type = 4; + mbi->motion_type = 2; + vmc = + mpeg2_dist2( + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), mb, + mpeg2_width, iminr & 1, jminr & 1, 16 ); + } else { + /* field, backward */ + mbi->mb_type = 4; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + newref + ( tselr ? mpeg2_width : 0 ) + ( imintr >> 1 ) + + ( mpeg2_width << 1 ) * ( jmintr >> 1 ), + mb, mpeg2_width << 1, imintr & 1, jmintr & 1, 8 ); + vmc += + mpeg2_dist2( + newref + ( bselr ? mpeg2_width : 0 ) + ( iminbr >> 1 ) + + ( mpeg2_width << 1 ) * ( jminbr >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbr & 1, jminbr & 1, 8 ); + } + } + + /* + select between intra or non-intra coding: + + selection is based on intra block variance (var) vs. + prediction error variance (vmc) + + blocks with small prediction error are always coded non-intra + even if variance is smaller (is this reasonable?) + */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + var = vmc; + + if ( mbi->motion_type == 2 ) { + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = iminf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jminf - ( j << 1 ); + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = iminr - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = jminr - ( j << 1 ); + } else { + /* these are FRAME vectors */ + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imintf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = ( jmintf << 1 ) - ( j << 1 ); + mbi->MV[ 1 ][ 0 ][ 0 ] = iminbf - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = ( jminbf << 1 ) - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = tself; + mbi->mv_field_sel[ 1 ][ 0 ] = bself; + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = imintr - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = ( jmintr << 1 ) - ( j << 1 ); + mbi->MV[ 1 ][ 1 ][ 0 ] = iminbr - ( i << 1 ); + mbi->MV[ 1 ][ 1 ][ 1 ] = ( jminbr << 1 ) - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 1 ] = tselr; + mbi->mv_field_sel[ 1 ][ 1 ] = bselr; + } + } + } + + mbi->var = var; +} + + +/* + motion estimation for field pictures + + oldorg: original frame for forward prediction (P and B frames) + neworg: original frame for backward prediction (B frames only) + oldref: reconstructed frame for forward prediction (P and B frames) + newref: reconstructed frame for backward prediction (B frames only) + cur: current original frame (the one for which the prediction is formed) + curref: current reconstructed frame (to predict second field from first) + sxf,syf: forward search window (frame coordinates) + sxb,syb: backward search window (frame coordinates) + mbi: pointer to macroblock info structure + secondfield: indicates second field of a frame (in P fields this means + that reference field of opposite parity is in curref instead + of oldref) + ipflag: indicates a P type field which is the second field of a frame + in which the first field is I type (this restricts predictions + to be based only on the opposite parity (=I) field) + + results: + mbi-> + mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD + MV[][][]: motion vectors (field format) + mv_field_sel: top/bottom field + motion_type: MC_FIELD, MC_16X8 + + uses global vars: mpeg2_pict_type, mpeg2_pict_struct +*/ +void mpeg2_field_ME( unsigned char *oldorg, unsigned char *neworg, + unsigned char *oldref, unsigned char *newref, + unsigned char *cur, unsigned char *curref, int i, int j, + int sxf, int syf, int sxb, int syb, struct mbinfo *mbi, + int secondfield, int ipflag ) +{ + int w2; + unsigned char *mb, *toporg, *topref, *botorg, *botref; + int var, vmc, v0, dmcfieldi, dmc8i; + int imin, jmin, imin8u, jmin8u, imin8l, jmin8l, dmcfield, dmc8, sel, sel8u, + sel8l; + int iminf, jminf, imin8uf, jmin8uf, imin8lf, jmin8lf, dmcfieldf, dmc8f, self, + sel8uf, sel8lf; + int iminr, jminr, imin8ur, jmin8ur, imin8lr, jmin8lr, dmcfieldr, dmc8r, selr, + sel8ur, sel8lr; + int imins, jmins, ds, imindmv, jmindmv, vmc_dp, dmc_dp; + + + w2 = mpeg2_width << 1; + mb = cur + i + w2 * j; + + if ( mpeg2_pict_struct == 2 ) + mb += mpeg2_width; + + var = mpeg2_variance( mb, w2 ); + + if ( mpeg2_pict_type == 1 ) + mbi->mb_type = 1; + else + + if ( mpeg2_pict_type == 2 ) { + toporg = oldorg; + topref = oldref; + botorg = oldorg + mpeg2_width; + botref = oldref + mpeg2_width; + + if ( secondfield ) { + /* opposite parity field is in same frame */ + if ( mpeg2_pict_struct == 1 ) { + /* current is top field */ + botorg = cur + mpeg2_width; + botref = curref + mpeg2_width; + } else { + /* current is bottom field */ + toporg = cur; + topref = curref; + } + } + + mpeg2_field_estimate( + toporg, topref, botorg, botref, mb, i, j, sxf, syf, ipflag, &imin, &jmin, + &imin8u, &jmin8u, &imin8l, &jmin8l, &dmcfield, &dmc8, &sel, &sel8u, + &sel8l, &imins, &jmins, &ds ); + + if ( ( mpeg2_M == 1 ) && !ipflag ) + /* generic condition which permits Dual Prime */ + mpeg2_dpfield_estimate( + topref, botref, mb, i, j, imins, jmins, &imindmv, &jmindmv, &dmc_dp, + &vmc_dp ); + + /* select between dual prime, field and 16x8 prediction */ + if ( ( mpeg2_M == 1 ) && !ipflag && ( dmc_dp < dmc8 ) && + ( dmc_dp < dmcfield ) ) { + /* Dual Prime prediction */ + mbi->motion_type = 3; + vmc = vmc_dp; /* we already calculated L2 error for Dual */ + + } else + + if ( dmc8 < dmcfield ) { + /* 16x8 prediction */ + mbi->motion_type = 2; + /* upper half block */ + vmc = + mpeg2_dist2( + ( sel8u ? botref : topref ) + ( imin8u >> 1 ) + w2 * ( jmin8u >> 1 ), + mb, w2, imin8u & 1, jmin8u & 1, 8 ); + /* lower half block */ + vmc += + mpeg2_dist2( + ( sel8l ? botref : topref ) + ( imin8l >> 1 ) + w2 * ( jmin8l >> 1 ), + mb + 8 * w2, w2, imin8l & 1, jmin8l & 1, 8 ); + } else { + /* field prediction */ + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + ( sel ? botref : topref ) + ( imin >> 1 ) + w2 * ( jmin >> 1 ), + mb, w2, imin & 1, jmin & 1, 16 ); + } + + /* select between intra and non-intra coding */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + /* + zero MV field prediction from same parity ref. field + (not allowed if ipflag is set) + */ + if ( !ipflag ) + v0 = + mpeg2_dist2( + ( ( mpeg2_pict_struct == 2 ) ? botref : topref ) + i + w2 * j, mb, + w2, 0, 0, 16 ); + + if ( ipflag || ( ( 4 * v0 > 5 * vmc ) && ( v0 >= 9 * 256 ) ) ) { + var = vmc; + mbi->mb_type = 8; + + if ( mbi->motion_type == 1 ) { + mbi->MV[ 0 ][ 0 ][ 0 ] = imin - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = sel; + } else + + if ( mbi->motion_type == 3 ) { + /* same parity vector */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imins - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmins - ( j << 1 ); + + /* opposite parity vector */ + mbi->dmvector[ 0 ] = imindmv; + mbi->dmvector[ 1 ] = jmindmv; + } else { + mbi->MV[ 0 ][ 0 ][ 0 ] = imin8u - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin8u - ( j << 1 ); + mbi->MV[ 1 ][ 0 ][ 0 ] = imin8l - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = jmin8l - ( ( j + 8 ) << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = sel8u; + mbi->mv_field_sel[ 1 ][ 0 ] = sel8l; + } + } else { + /* No MC */ + var = v0; + mbi->mb_type = 0; + mbi->motion_type = 1; + mbi->MV[ 0 ][ 0 ][ 0 ] = 0; + mbi->MV[ 0 ][ 0 ][ 1 ] = 0; + mbi->mv_field_sel[ 0 ][ 0 ] = ( mpeg2_pict_struct == 2 ); + } + } + } else { /* if (mpeg2_pict_type==B_TYPE) */ + /* forward prediction */ + mpeg2_field_estimate( + oldorg, oldref, oldorg + mpeg2_width, oldref + mpeg2_width, mb, i, j, sxf, + syf, 0, &iminf, &jminf, &imin8uf, &jmin8uf, &imin8lf, &jmin8lf, + &dmcfieldf, &dmc8f, &self, &sel8uf, &sel8lf, &imins, &jmins, &ds ); + + /* backward prediction */ + mpeg2_field_estimate( + neworg, newref, neworg + mpeg2_width, newref + mpeg2_width, mb, i, j, sxb, + syb, 0, &iminr, &jminr, &imin8ur, &jmin8ur, &imin8lr, &jmin8lr, + &dmcfieldr, &dmc8r, &selr, &sel8ur, &sel8lr, &imins, &jmins, &ds ); + + /* calculate distances for bidirectional prediction */ + /* field */ + dmcfieldi = + mpeg2_bdist1( + oldref + ( self ? mpeg2_width : 0 ) + ( iminf >> 1 ) + + w2 * ( jminf >> 1 ), + newref + ( selr ? mpeg2_width : 0 ) + ( iminr >> 1 ) + + w2 * ( jminr >> 1 ), + mb, w2, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + + /* 16x8 upper half block */ + dmc8i = + mpeg2_bdist1( + oldref + ( sel8uf ? mpeg2_width : 0 ) + ( imin8uf >> 1 ) + + w2 * ( jmin8uf >> 1 ), + newref + ( sel8ur ? mpeg2_width : 0 ) + ( imin8ur >> 1 ) + + w2 * ( jmin8ur >> 1 ), + mb, w2, imin8uf & 1, jmin8uf & 1, imin8ur & 1, jmin8ur & 1, 8 ); + + /* 16x8 lower half block */ + dmc8i += + mpeg2_bdist1( + oldref + ( sel8lf ? mpeg2_width : 0 ) + ( imin8lf >> 1 ) + + w2 * ( jmin8lf >> 1 ), + newref + ( sel8lr ? mpeg2_width : 0 ) + ( imin8lr >> 1 ) + + w2 * ( jmin8lr >> 1 ), + mb + 8 * w2, w2, imin8lf & 1, jmin8lf & 1, imin8lr & 1, jmin8lr & 1, + 8 ); + + /* select prediction type of minimum distance */ + if ( ( dmcfieldi < dmc8i ) && ( dmcfieldi < dmcfieldf ) && + ( dmcfieldi < dmc8f ) && ( dmcfieldi < dmcfieldr ) && + ( dmcfieldi < dmc8r ) ) { + /* field, interpolated */ + mbi->mb_type = 8 | 5; + mbi->motion_type = 1; + vmc = + mpeg2_bdist2( + oldref + ( self ? mpeg2_width : 0 ) + ( iminf >> 1 ) + + w2 * ( jminf >> 1 ), + newref + ( selr ? mpeg2_width : 0 ) + ( iminr >> 1 ) + + w2 * ( jminr >> 1 ), + mb, w2, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + } else + + if ( ( dmc8i < dmcfieldf ) && ( dmc8i < dmc8f ) && ( dmc8i < dmcfieldr ) && + ( dmc8i < dmc8r ) ) { + /* 16x8, interpolated */ + mbi->mb_type = 8 | 4; + mbi->motion_type = 2; + + /* upper half block */ + vmc = + mpeg2_bdist2( + oldref + ( sel8uf ? mpeg2_width : 0 ) + ( imin8uf >> 1 ) + + w2 * ( jmin8uf >> 1 ), + newref + ( sel8ur ? mpeg2_width : 0 ) + ( imin8ur >> 1 ) + + w2 * ( jmin8ur >> 1 ), + mb, w2, imin8uf & 1, jmin8uf & 1, imin8ur & 1, jmin8ur & 1, 8 ); + + /* lower half block */ + vmc += + mpeg2_bdist2( + oldref + ( sel8lf ? mpeg2_width : 0 ) + ( imin8lf >> 1 ) + + w2 * ( jmin8lf >> 1 ), + newref + ( sel8lr ? mpeg2_width : 0 ) + ( imin8lr >> 1 ) + + w2 * ( jmin8lr >> 1 ), + mb + 8 * w2, w2, imin8lf & 1, jmin8lf & 1, imin8lr & 1, jmin8lr & 1, + 8 ); + } else + + if ( ( dmcfieldf < dmc8f ) && ( dmcfieldf < dmcfieldr ) && + ( dmcfieldf < dmc8r ) ) { + /* field, forward */ + mbi->mb_type = 8; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + oldref + ( self ? mpeg2_width : 0 ) + ( iminf >> 1 ) + + w2 * ( jminf >> 1 ), + mb, w2, iminf & 1, jminf & 1, 16 ); + } else + + if ( ( dmc8f < dmcfieldr ) && ( dmc8f < dmc8r ) ) { + /* 16x8, forward */ + mbi->mb_type = 8; + mbi->motion_type = 2; + + /* upper half block */ + vmc = + mpeg2_dist2( + oldref + ( sel8uf ? mpeg2_width : 0 ) + ( imin8uf >> 1 ) + + w2 * ( jmin8uf >> 1 ), mb, w2, imin8uf & 1, jmin8uf & 1, 8 ); + + /* lower half block */ + vmc += + mpeg2_dist2( + oldref + ( sel8lf ? mpeg2_width : 0 ) + ( imin8lf >> 1 ) + + w2 * ( jmin8lf >> 1 ), + mb + 8 * w2, w2, imin8lf & 1, jmin8lf & 1, 8 ); + } else + + if ( dmcfieldr < dmc8r ) { + /* field, backward */ + mbi->mb_type = 4; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + newref + ( selr ? mpeg2_width : 0 ) + ( iminr >> 1 ) + + w2 * ( jminr >> 1 ), + mb, w2, iminr & 1, jminr & 1, 16 ); + } else { + /* 16x8, backward */ + mbi->mb_type = 4; + mbi->motion_type = 2; + + /* upper half block */ + vmc = + mpeg2_dist2( + newref + ( sel8ur ? mpeg2_width : 0 ) + ( imin8ur >> 1 ) + + w2 * ( jmin8ur >> 1 ), + mb, w2, imin8ur & 1, jmin8ur & 1, 8 ); + + /* lower half block */ + vmc += + mpeg2_dist2( + newref + ( sel8lr ? mpeg2_width : 0 ) + ( imin8lr >> 1 ) + + w2 * ( jmin8lr >> 1 ), + mb + 8 * w2, w2, imin8lr & 1, jmin8lr & 1, 8 ); + } + + /* select between intra and non-intra coding */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + var = vmc; + + if ( mbi->motion_type == 1 ) { + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = iminf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jminf - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = self; + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = iminr - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = jminr - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 1 ] = selr; + } else { /* MC_16X8 */ + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imin8uf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin8uf - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = sel8uf; + mbi->MV[ 1 ][ 0 ][ 0 ] = imin8lf - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = jmin8lf - ( ( j + 8 ) << 1 ); + mbi->mv_field_sel[ 1 ][ 0 ] = sel8lf; + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = imin8ur - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = jmin8ur - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 1 ] = sel8ur; + mbi->MV[ 1 ][ 1 ][ 0 ] = imin8lr - ( i << 1 ); + mbi->MV[ 1 ][ 1 ][ 1 ] = jmin8lr - ( ( j + 8 ) << 1 ); + mbi->mv_field_sel[ 1 ][ 1 ] = sel8lr; + } + } + } + + mbi->var = var; +} + + +/* + frame picture motion estimation + + org: top left pel of source reference frame + ref: top left pel of reconstructed reference frame + mb: macroblock to be matched + i,j: location of mb relative to ref (=center of search window) + sx,sy: half widths of search window + iminp,jminp,dframep: location and value of best frame prediction + imintp,jmintp,tselp: location of best field pred. for top field of mb + iminbp,jminbp,bselp: location of best field pred. for bottom field of mb + dfieldp: value of field prediction +*/ +void mpeg2_frame_estimate( unsigned char *org, unsigned char *ref, + unsigned char *mb, int i, int j, int sx, int sy, + int *iminp, int *jminp, int *imintp, int *jmintp, + int *iminbp, int *jminbp, int *dframep, int *dfieldp, + int *tselp, int *bselp, int imins[ 2 ][ 2 ], + int jmins[ 2 ][ 2 ] ) +{ + int dt, db, dmint, dminb; + int imint, iminb, jmint, jminb; + + + /* frame prediction */ + *dframep = + mpeg2_fullsearch( + org, ref, mb, mpeg2_width, i, j, sx, sy, 16, mpeg2_width, mpeg2_height, + iminp, jminp ); + + /* predict top field from top field */ + dt = + mpeg2_fullsearch( + org, ref, mb, mpeg2_width << 1, i, j>>1, sx, sy >> 1, 8, mpeg2_width, + mpeg2_height >> 1, &imint, &jmint ); + + /* predict top field from bottom field */ + db = + mpeg2_fullsearch( + org + mpeg2_width, ref + mpeg2_width, mb, mpeg2_width << 1, i, j>>1, sx, + sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &iminb, &jminb ); + + imins[ 0 ][ 0 ] = imint; + jmins[ 0 ][ 0 ] = jmint; + imins[ 1 ][ 0 ] = iminb; + jmins[ 1 ][ 0 ] = jminb; + + /* select prediction for top field */ + if ( dt <= db ) { + dmint = dt; + *imintp = imint; + *jmintp = jmint; + *tselp = 0; + } else { + dmint = db; + *imintp = iminb; + *jmintp = jminb; + *tselp = 1; + } + + /* predict bottom field from top field */ + dt = + mpeg2_fullsearch( + org, ref, mb + mpeg2_width, mpeg2_width << 1, i, j>>1, sx, sy >> 1, 8, + mpeg2_width, mpeg2_height >> 1, &imint, &jmint ); + + /* predict bottom field from bottom field */ + db = + mpeg2_fullsearch( + org + mpeg2_width, ref + mpeg2_width, mb + mpeg2_width, mpeg2_width << 1, + i, j>>1, sx, sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &iminb, &jminb ); + + imins[ 0 ][ 1 ] = imint; + jmins[ 0 ][ 1 ] = jmint; + imins[ 1 ][ 1 ] = iminb; + jmins[ 1 ][ 1 ] = jminb; + + /* select prediction for bottom field */ + if ( db <= dt ) { + dminb = db; + *iminbp = iminb; + *jminbp = jminb; + *bselp = 1; + } else { + dminb = dt; + *iminbp = imint; + *jminbp = jmint; + *bselp = 0; + } + + *dfieldp = dmint + dminb; +} + + +/* + field picture motion estimation subroutine + + toporg: address of original top reference field + topref: address of reconstructed top reference field + botorg: address of original bottom reference field + botref: address of reconstructed bottom reference field + mb: macroblock to be matched + i,j: location of mb (=center of search window) + sx,sy: half width/height of search window + + iminp,jminp,selp,dfieldp: location and distance of best field prediction + imin8up,jmin8up,sel8up: location of best 16x8 pred. for upper half of mb + imin8lp,jmin8lp,sel8lp: location of best 16x8 pred. for lower half of mb + d8p: distance of best 16x8 prediction + iminsp,jminsp,dsp: location and distance of best same parity field + prediction (needed for dual prime, only valid if + ipflag==0) +*/ +void mpeg2_field_estimate( unsigned char *toporg, unsigned char *topref, + unsigned char *botorg, unsigned char *botref, + unsigned char *mb, int i, int j, int sx, int sy, + int ipflag, int *iminp, int *jminp, int *imin8up, + int *jmin8up, int *imin8lp, int *jmin8lp, + int *dfieldp, int *d8p, int *selp, int *sel8up, + int *sel8lp, int *iminsp, int *jminsp, int *dsp ) +{ + int dt, db, imint, jmint, iminb, jminb, notop, nobot; + + + /* if ipflag is set, predict from field of opposite parity only */ + notop = ipflag && ( mpeg2_pict_struct == 1 ); + nobot = ipflag && ( mpeg2_pict_struct == 2 ); + + /* field prediction */ + + /* predict current field from top field */ + if ( notop ) + dt = 65536; /* infinity */ + else + dt = + mpeg2_fullsearch( + toporg, topref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 16, mpeg2_width, + mpeg2_height >> 1, &imint, &jmint ); + + /* predict current field from bottom field */ + if ( nobot ) + db = 65536; /* infinity */ + else + db = + mpeg2_fullsearch( + botorg, botref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 16, mpeg2_width, + mpeg2_height >> 1, &iminb, &jminb ); + + /* same parity prediction (only valid if ipflag==0) */ + if ( mpeg2_pict_struct == 1 ) { + *iminsp = imint; + *jminsp = jmint; + *dsp = dt; + } else { + *iminsp = iminb; + *jminsp = jminb; + *dsp = db; + } + + /* select field prediction */ + if ( dt <= db ) { + *dfieldp = dt; + *iminp = imint; + *jminp = jmint; + *selp = 0; + } else { + *dfieldp = db; + *iminp = iminb; + *jminp = jminb; + *selp = 1; + } + + + /* 16x8 motion compensation */ + + /* predict upper half field from top field */ + if ( notop ) + dt = 65536; + else + dt = + mpeg2_fullsearch( + toporg, topref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 8, mpeg2_width, + mpeg2_height >> 1, &imint, &jmint ); + + /* predict upper half field from bottom field */ + if ( nobot ) + db = 65536; + else + db = + mpeg2_fullsearch( + botorg, botref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 8, mpeg2_width, + mpeg2_height >> 1, &iminb, &jminb ); + + /* select prediction for upper half field */ + if ( dt <= db ) { + *d8p = dt; + *imin8up = imint; + *jmin8up = jmint; + *sel8up = 0; + } else { + *d8p = db; + *imin8up = iminb; + *jmin8up = jminb; + *sel8up = 1; + } + + /* predict lower half field from top field */ + if ( notop ) + dt = 65536; + else + dt = + mpeg2_fullsearch( + toporg, topref, mb + ( mpeg2_width << 4 ), mpeg2_width << 1, i, j + 8, + sx, sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &imint, &jmint ); + + /* predict lower half field from bottom field */ + if ( nobot ) + db = 65536; + else + db = + mpeg2_fullsearch( + botorg, botref, mb + ( mpeg2_width << 4 ), mpeg2_width << 1, i, j + 8, + sx, sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &iminb, &jminb ); + + /* select prediction for lower half field */ + if ( dt <= db ) { + *d8p += dt; + *imin8lp = imint; + *jmin8lp = jmint; + *sel8lp = 0; + } else { + *d8p += db; + *imin8lp = iminb; + *jmin8lp = jminb; + *sel8lp = 1; + } +} + + +void mpeg2_dpframe_estimate( unsigned char *ref, unsigned char *mb, int i, + int j, int iminf[ 2 ][ 2 ], int jminf[ 2 ][ 2 ], + int *iminp, int *jminp, int *imindmvp, + int *jmindmvp, int *dmcp, int *vmcp ) +{ + int pref, ppred, delta_x, delta_y; + int is, js, it, jt, ib, jb, it0, jt0, ib0, jb0; + int imins, jmins, imint, jmint, iminb, jminb, imindmv, jmindmv; + int vmc, local_dist; + + + /* + Calculate Dual Prime distortions for 9 delta candidates + for each of the four minimum field vectors + Note: only for P pictures! + */ + + /* initialize minimum dual prime distortion to large value */ + vmc = 1 << 30; + + _Pragma( "loopbound min 2 max 2" ) + for ( pref = 0; pref < 2; pref++ ) { + ppred = 0; + _Pragma( "loopbound min 2 max 2" ) + for ( ; ppred < 2; ppred++ ) { + /* + convert Cartesian absolute to relative motion vector + values (wrt current macroblock address (i,j) + */ + is = iminf[ pref ][ ppred ] - ( i << 1 ); + js = jminf[ pref ][ ppred ] - ( j << 1 ); + + if ( pref != ppred ) { + /* vertical field shift adjustment */ + if ( ppred == 0 ) + js++; + else + js--; + + /* mvxs and mvys scaling*/ + is <<= 1; + js <<= 1; + if ( mpeg2_topfirst == ppred ) { + /* second field: scale by 1/3 */ + is = ( is >= 0 ) ? ( is + 1 ) / 3 : -( ( -is + 1 ) / 3 ); + js = ( js >= 0 ) ? ( js + 1 ) / 3 : -( ( -js + 1 ) / 3 ); + } else + continue; + } + + /* vector for prediction from field of opposite 'parity' */ + if ( mpeg2_topfirst ) { + /* vector for prediction of top field from bottom field */ + it0 = ( ( is + ( is > 0 ) ) >> 1 ); + jt0 = ( ( js + ( js > 0 ) ) >> 1 ) - 1; + + /* vector for prediction of bottom field from top field */ + ib0 = ( ( 3 * is + ( is > 0 ) ) >> 1 ); + jb0 = ( ( 3 * js + ( js > 0 ) ) >> 1 ) + 1; + } else { + /* vector for prediction of top field from bottom field */ + it0 = ( ( 3 * is + ( is > 0 ) ) >> 1 ); + jt0 = ( ( 3 * js + ( js > 0 ) ) >> 1 ) - 1; + + /* vector for prediction of bottom field from top field */ + ib0 = ( ( is + ( is > 0 ) ) >> 1 ); + jb0 = ( ( js + ( js > 0 ) ) >> 1 ) + 1; + } + + /* convert back to absolute half-pel field picture coordinates */ + is += i << 1; + js += j << 1; + it0 += i << 1; + jt0 += j << 1; + ib0 += i << 1; + jb0 += j << 1; + + if ( ( is >= 0 ) && ( is <= ( mpeg2_width - 16 ) << 1 ) && + ( js >= 0 ) && ( js <= ( mpeg2_height - 16 ) ) ) { + _Pragma( "loopbound min 3 max 3" ) + for ( delta_y = -1; delta_y <= 1; delta_y++ ) { + delta_x = -1; + _Pragma( "loopbound min 3 max 3" ) + for ( ; delta_x <= 1; delta_x++ ) { + /* opposite field coordinates */ + it = it0 + delta_x; + jt = jt0 + delta_y; + ib = ib0 + delta_x; + jb = jb0 + delta_y; + + if ( ( it >= 0 ) && ( it <= ( mpeg2_width - 16 ) << 1 ) && + ( jt >= 0 ) && ( jt <= ( mpeg2_height - 16 ) ) && + ( ib >= 0 ) && ( ib <= ( mpeg2_width - 16 ) << 1 ) && + ( jb >= 0 ) && ( jb <= ( mpeg2_height - 16 ) ) ) { + /* compute prediction error */ + local_dist = + mpeg2_bdist2( + ref + ( is >> 1 ) + ( mpeg2_width << 1 ) * ( js >> 1 ), + ref + mpeg2_width + ( it >> 1 ) + + ( mpeg2_width << 1 ) * ( jt >> 1 ), + mb, /* current mb location */ + mpeg2_width << 1, /* adjacent line distance */ + is & 1, js & 1, it & 1, jt & 1, /* half-pel flags */ + 8 ); /* block height */ + local_dist += + mpeg2_bdist2( + ref + mpeg2_width + ( is >> 1 ) + + ( mpeg2_width << 1 ) * ( js >> 1 ), + ref + ( ib >> 1 ) + ( mpeg2_width << 1 ) * ( jb >> 1 ), + mb + mpeg2_width, /* current mb location */ + mpeg2_width << 1, /* adjacent line distance */ + is & 1, js & 1, ib & 1, jb & 1, /* half-pel flags */ + 8 ); /* block height */ + + /* update delta with least distortion vector */ + if ( local_dist < vmc ) { + imins = is; + jmins = js; + imint = it; + jmint = jt; + iminb = ib; + jminb = jb; + imindmv = delta_x; + jmindmv = delta_y; + vmc = local_dist; + } + } + } /* end delta x loop */ + } /* end delta y loop */ + } + } + } + + /* Compute L1 error for decision purposes */ + local_dist = + mpeg2_bdist1( + ref + ( imins >> 1 ) + ( mpeg2_width << 1 ) * ( jmins >> 1 ), + ref + mpeg2_width + ( imint >> 1 ) + + ( mpeg2_width << 1 ) * ( jmint >> 1 ), + mb, mpeg2_width << 1, imins & 1, jmins & 1, imint & 1, jmint & 1, 8 ); + local_dist += + mpeg2_bdist1( + ref + mpeg2_width + ( imins >> 1 ) + + ( mpeg2_width << 1 ) * ( jmins >> 1 ), + ref + ( iminb >> 1 ) + ( mpeg2_width << 1 ) * ( jminb >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, imins & 1, jmins & 1, iminb & 1, + jminb & 1, 8 ); + + *dmcp = local_dist; + *iminp = imins; + *jminp = jmins; + *imindmvp = imindmv; + *jmindmvp = jmindmv; + *vmcp = vmc; +} + + +void mpeg2_dpfield_estimate( unsigned char *topref, unsigned char *botref, + unsigned char *mb, int i, int j, int imins, + int jmins, int *imindmvp, int *jmindmvp, int *dmcp, + int *vmcp ) +{ + unsigned char *sameref, *oppref; + int io0, jo0, io, jo, delta_x, delta_y, mvxs, mvys, mvxo0, mvyo0; + int imino, jmino, imindmv, jmindmv, vmc_dp, local_dist; + + + /* Calculate Dual Prime distortions for 9 delta candidates */ + /* Note: only for P pictures! */ + + /* Assign opposite and same reference pointer */ + if ( mpeg2_pict_struct == 1 ) { + sameref = topref; + oppref = botref; + } else { + sameref = botref; + oppref = topref; + } + + /* + convert Cartesian absolute to relative motion vector + values (wrt current macroblock address (i,j) + */ + mvxs = imins - ( i << 1 ); + mvys = jmins - ( j << 1 ); + + /* vector for prediction from field of opposite 'parity' */ + mvxo0 = ( mvxs + ( mvxs > 0 ) ) >> 1; /* mvxs // 2 */ + mvyo0 = ( mvys + ( mvys > 0 ) ) >> 1; /* mvys // 2 */ + + /* vertical field shift correction */ + if ( mpeg2_pict_struct == 1 ) + mvyo0--; + else + mvyo0++; + + /* convert back to absolute coordinates */ + io0 = mvxo0 + ( i << 1 ); + jo0 = mvyo0 + ( j << 1 ); + + /* initialize minimum dual prime distortion to large value */ + vmc_dp = 1 << 30; + + _Pragma( "loopbound min 3 max 3" ) + for ( delta_y = -1; delta_y <= 1; delta_y++ ) { + delta_x = -1; + _Pragma( "loopbound min 3 max 3" ) + for ( ; delta_x <= 1; delta_x++ ) { + /* opposite field coordinates */ + io = io0 + delta_x; + jo = jo0 + delta_y; + + if ( ( io >= 0 ) && ( io <= ( mpeg2_width - 16 ) << 1 ) && + ( jo >= 0 ) && ( jo <= ( mpeg2_height2 - 16 ) << 1 ) ) { + /* compute prediction error */ + local_dist = + mpeg2_bdist2( + sameref + ( imins >> 1 ) + mpeg2_width2 * ( jmins >> 1 ), + oppref + ( io >> 1 ) + mpeg2_width2 * ( jo >> 1 ), + mb, /* current mb location */ + mpeg2_width2, /* adjacent line distance */ + imins & 1, jmins & 1, io & 1, jo & 1, /* half-pel flags */ + 16 ); /* block height */ + + /* update delta with least distortion vector */ + if ( local_dist < vmc_dp ) { + imino = io; + jmino = jo; + imindmv = delta_x; + jmindmv = delta_y; + vmc_dp = local_dist; + } + } + } /* end delta x loop */ + } /* end delta y loop */ + + /* Compute L1 error for decision purposes */ + *dmcp = + mpeg2_bdist1( + sameref + ( imins >> 1 ) + mpeg2_width2 * ( jmins >> 1 ), + oppref + ( imino >> 1 ) + mpeg2_width2 * ( jmino >> 1 ), + mb, /* current mb location */ + mpeg2_width2, /* adjacent line distance */ + imins & 1, jmins & 1, imino & 1, jmino & 1, /* half-pel flags */ + 16 ); /* block height */ + + *imindmvp = imindmv; + *jmindmvp = jmindmv; + *vmcp = vmc_dp; +} + + +/* + full search block matching + + blk: top left pel of (16*h) block + h: height of block + lx: distance (in bytes) of vertically adjacent pels in ref,blk + org: top left pel of source reference picture + ref: top left pel of reconstructed reference picture + i0,j0: center of search window + sx,sy: half widths of search window + xmax,ymax: right/bottom limits of search area + iminp,jminp: pointers to where the result is stored + result is given as half pel offset from ref(0,0) + i.e. NOT relative to (i0,j0) +*/ +int mpeg2_fullsearch( unsigned char *org, unsigned char *ref, + unsigned char *blk, int lx, int i0, int j0, int sx, + int sy, int h, int xmax, int ymax, int *iminp, + int *jminp ) +{ + int i, j, imin, jmin, ilow, ihigh, jlow, jhigh; + int d, dmin; + int k, l, sxy; + + + ilow = i0 - sx; + ihigh = i0 + sx; + + if ( ilow < 0 ) + ilow = 0; + + if ( ihigh > xmax - 16 ) + ihigh = xmax - 16; + + jlow = j0 - sy; + jhigh = j0 + sy; + + if ( jlow < 0 ) + jlow = 0; + + if ( jhigh > ymax - h ) + jhigh = ymax - h; + + /* full pel search, spiraling outwards */ + + imin = i0; + jmin = j0; + dmin = mpeg2_dist1( org + imin + lx * jmin, blk, lx, 0, 0, h, 65536 ); + + sxy = ( sx > sy ) ? sx : sy; + + _Pragma( "loopbound min 3 max 7" ) + for ( l = 1; l <= sxy; l++ ) { + i = i0 - l; + j = j0 - l; + _Pragma( "loopbound min 8 max 56" ) + for ( k = 0; k < 8 * l; k++ ) { + if ( ( i >= ilow ) && ( i <= ihigh ) && ( j >= jlow ) && + ( j <= jhigh ) ) { + d = mpeg2_dist1( org + i + lx * j, blk, lx, 0, 0, h, dmin ); + + if ( d < dmin ) { + dmin = d; + imin = i; + jmin = j; + } + } + + if ( k < 2 * l ) + i++; + else + + if ( k < 4 * l ) + j++; + else + + if ( k < 6 * l ) + i--; + else + j--; + } + } + + /* half pel */ + dmin = 65536; + imin <<= 1; + jmin <<= 1; + ilow = imin - ( imin > 0 ); + ihigh = imin + ( imin < ( ( xmax - 16 ) << 1 ) ); + jlow = jmin - ( jmin > 0 ); + jhigh = jmin + ( jmin < ( ( ymax - h ) << 1 ) ); + + _Pragma( "loopbound min 2 max 3" ) + for ( j = jlow; j <= jhigh; j++ ) { + i = ilow; + _Pragma( "loopbound min 2 max 3" ) + for ( ; i <= ihigh; i++ ) { + d = + mpeg2_dist1( + ref + ( i >> 1 ) + lx * ( j >> 1 ), blk, lx, i & 1, j & 1, h, dmin ); + + if ( d < dmin ) { + dmin = d; + imin = i; + jmin = j; + } + } + } + + *iminp = imin; + *jminp = jmin; + + return( dmin ); +} + + +/* + total absolute difference between two (16*h) blocks + including optional half pel interpolation of blk1 (hx,hy) + blk1,blk2: addresses of top left pels of both blocks + lx: distance (in bytes) of vertically adjacent pels + hx,hy: flags for horizontal and/or vertical interpolation + h: height of block (usually 8 or 16) + distlim: bail out if sum exceeds this value +*/ +int mpeg2_dist1( unsigned char *blk1, unsigned char *blk2, int lx, int hx, + int hy, int h, int distlim ) +{ + unsigned char *p1, *p1a, *p2; + int i, j; + int s, v; + + + s = 0; + p1 = blk1; + p2 = blk2; + + if ( !hx && !hy ) { + _Pragma( "loopbound min 1 max 16" ) + for ( j = 0; j < h; j++ ) { + if ( ( v = p1[ 0 ] - p2[ 0 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 1 ] - p2[ 1 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 2 ] - p2[ 2 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 3 ] - p2[ 3 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 4 ] - p2[ 4 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 5 ] - p2[ 5 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 6 ] - p2[ 6 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 7 ] - p2[ 7 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 8 ] - p2[ 8 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 9 ] - p2[ 9 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 10 ] - p2[ 10 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 11 ] - p2[ 11 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 12 ] - p2[ 12 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 13 ] - p2[ 13 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 14 ] - p2[ 14 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 15 ] - p2[ 15 ] ) < 0 ) + v = -v; + s += v; + + if ( s >= distlim ) + break; + + p1 += lx; + p2 += lx; + } + } else + + if ( hx && !hy ) { + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1[ i + 1 ] + 1 ) >> 1 ) - p2[ i ]; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p1 += lx; + p2 += lx; + } + } else + + if ( !hx && hy ) { + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1a[ i ] + 1 ) >> 1 ) - p2[ i ]; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } else { /* if (hx && hy) */ + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( unsigned int ) + ( p1[ i ] + p1[ i + 1 ] + p1a[ i ] + p1a[ i + 1 ] + 2 ) >> 2 ) - + p2[ i ]; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } + + return( s ); +} + + +/* + total squared difference between two (16*h) blocks + including optional half pel interpolation of blk1 (hx,hy) + blk1,blk2: addresses of top left pels of both blocks + lx: distance (in bytes) of vertically adjacent pels + hx,hy: flags for horizontal and/or vertical interpolation + h: height of block (usually 8 or 16) +*/ +int mpeg2_dist2( unsigned char *blk1, unsigned char *blk2, int lx, int hx, + int hy, int h ) +{ + unsigned char *p1, *p1a, *p2; + int i, j; + int s, v; + + + s = 0; + p1 = blk1; + p2 = blk2; + + if ( !hx && !hy ) { + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = p1[ i ] - p2[ i ]; + s += v * v; + } + p1 += lx; + p2 += lx; + } + } else + + if ( hx && !hy ) { + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1[ i + 1 ] + 1 ) >> 1 ) - p2[ i ]; + s += v * v; + } + p1 += lx; + p2 += lx; + } + } else + + if ( !hx && hy ) { + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1a[ i ] + 1 ) >> 1 ) - p2[ i ]; + s += v * v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } else { /* if (hx && hy) */ + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( unsigned int ) + ( p1[ i ] + p1[ i + 1 ] + p1a[ i ] + p1a[ i + 1 ] + 2 ) >> 2 ) - + p2[ i ]; + s += v * v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } + + return( s ); +} + + +/* + absolute difference error between a (16*h) block and a bidirectional + prediction + + p2: address of top left pel of block + pf,hxf,hyf: address and half pel flags of forward ref. block + pb,hxb,hyb: address and half pel flags of backward ref. block + h: height of block + lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb +*/ +int mpeg2_bdist1( unsigned char *pf, unsigned char *pb, unsigned char *p2, + int lx, int hxf, int hyf, int hxb, int hyb, int h ) +{ + unsigned char *pfa, *pfb, *pfc, *pba, *pbb, *pbc; + int i, j; + int s, v; + + + pfa = pf + hxf; + pfb = pf + lx * hyf; + pfc = pfb + hxf; + + pba = pb + hxb; + pbb = pb + lx * hyb; + pbc = pbb + hxb; + + s = 0; + + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( ( ( unsigned int )( *pf++ + *pfa++ + *pfb++ + *pfc++ + 2 ) >> 2 ) + + ( ( unsigned int )( *pb++ + *pba++ + *pbb++ + *pbc++ + 2 ) >> 2 ) + + 1 ) >> 1 ) - + *p2++; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p2 += lx - 16; + pf += lx - 16; + pfa += lx - 16; + pfb += lx - 16; + pfc += lx - 16; + pb += lx - 16; + pba += lx - 16; + pbb += lx - 16; + pbc += lx - 16; + } + + return( s ); +} + + +/* + squared error between a (16*h) block and a bidirectional + prediction + + p2: address of top left pel of block + pf,hxf,hyf: address and half pel flags of forward ref. block + pb,hxb,hyb: address and half pel flags of backward ref. block + h: height of block + lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb +*/ +int mpeg2_bdist2( unsigned char *pf, unsigned char *pb, unsigned char *p2, + int lx, int hxf, int hyf, int hxb, int hyb, int h ) +{ + unsigned char *pfa, *pfb, *pfc, *pba, *pbb, *pbc; + int i, j; + int s, v; + + + pfa = pf + hxf; + pfb = pf + lx * hyf; + pfc = pfb + hxf; + + pba = pb + hxb; + pbb = pb + lx * hyb; + pbc = pbb + hxb; + + s = 0; + + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( ( ( unsigned int )( *pf++ + *pfa++ + *pfb++ + *pfc++ + 2 ) >> 2 ) + + ( ( unsigned int )( *pb++ + *pba++ + *pbb++ + *pbc++ + 2 ) >> 2 ) + + 1 ) >> 1 ) - + *p2++; + s += v * v; + } + p2 += lx - 16; + pf += lx - 16; + pfa += lx - 16; + pfb += lx - 16; + pfc += lx - 16; + pb += lx - 16; + pba += lx - 16; + pbb += lx - 16; + pbc += lx - 16; + } + + return( s ); +} + + +/* + variance of a (16*16) block, multiplied by 256 + p: address of top left pel of block + lx: distance (in bytes) of vertically adjacent pels +*/ +int mpeg2_variance( unsigned char *p, int lx ) +{ + int i, j; + unsigned int v, s, s2; + + + s = s2 = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( j = 0; j < 16; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = *p++; + s += v; + s2 += v * v; + } + p += lx - 16; + } + + return( s2 - ( s * s ) / 256 ); +} + + +/* + Main functions +*/ + +void _Pragma ( "entrypoint" ) mpeg2_main( void ) +{ + mpeg2_motion_estimation( + mpeg2_oldorgframe, mpeg2_oldorgframe, mpeg2_oldorgframe, mpeg2_oldorgframe, + mpeg2_oldorgframe, mpeg2_oldorgframe, 7, 7, 3, 3, mpeg2_mbinfo, 0, 0 ); +} + + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= 1; j--, k-- ) { + ndes_icd.r = ( ndes_icd.r << 1 ) | ndes_getbit( key, ndes_ipc1[j], 32 ); + ndes_icd.l = ndes_icd.l << 1; + ndes_icd.l = ( ndes_icd.l ) | ndes_getbit( key, ndes_ipc1[k], 32 ); + } + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 1; i <= 16; i++ ) { + pg = kns[i]; + ndes_ks( /* key,*/ i, &pg ); + kns[i] = pg; + } + } + + itmp.r = itmp.l = 0L; + + _Pragma( "loopbound min 32 max 32" ) + for ( j = 32, k = 64; j >= 1; j--, k-- ) { + itmp.r = itmp.r << 1; + itmp.r = ( itmp.r ) | ndes_getbit( inp, ip[j], 32 ); + itmp.l = itmp.l << 1; + itmp.l = ( itmp.l ) | ndes_getbit( inp, ip[k], 32 ); + } + _Pragma( "loopbound min 16 max 16" ) + for ( i = 1; i <= 16; i++ ) { + ii = ( isw == 1 ? 17 - i : i ); + ndes_cyfun( itmp.l, kns[ii], &ic ); + ic ^= itmp.r; + itmp.r = itmp.l; + itmp.l = ic; + } + + ic = itmp.r; + itmp.r = itmp.l; + itmp.l = ic; + ( *out ).r = ( *out ).l = 0L; + + _Pragma( "loopbound min 32 max 32" ) + for ( j = 32, k = 64; j >= 1; j--, k-- ) { + ( *out ).r = ( *out ).r << 1; + ( *out ).r = ( ( *out ).r ) | ndes_getbit( itmp, ipm[j], 32 ); + ( *out ).l = ( *out ).l << 1; + ( *out ).l = ( ( *out ).l ) | ndes_getbit( itmp, ipm[k], 32 ); + } +} + + +void ndes_cyfun( unsigned long ir, ndes_great k, unsigned long *iout ) +{ + volatile long iet[49] = {0, 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, + 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, + 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 + }; + volatile long ipp[33] = {0, 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, + 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, + 30, 6, 22, 11, 4, 25 + }; + volatile long is[16][4][9] = {{{ 0 , 14 , 15 , 10 , 7 , 2 , 12 , 4 , 13 }, + { 0 , 0 , 3 , 13 , 13 , 14 , 10 , 13 , 1 }, + { 0 , 4 , 0 , 13 , 10 , 4 , 9 , 1 , 7 }, + { 0 , 15 , 13 , 1 , 3 , 11 , 4 , 6 , 2 }}, + {{ 0 , 4 , 1 , 0 , 13 , 12 , 1 , 11 , 2 }, + { 0 , 15 , 13 , 7 , 8 , 11 , 15 , 0 , 15 }, + { 0 , 1 , 14 , 6 , 6 , 2 , 14 , 4 , 11 }, + { 0 , 12 , 8 , 10 , 15 , 8 , 3 , 11 , 1 }}, + {{ 0 , 13 , 8 , 9 , 14 , 4 , 10 , 2 , 8 }, + { 0 , 7 , 4 , 0 , 11 , 2 , 4 , 11 , 13 }, + { 0 , 14 , 7 , 4 , 9 , 1 , 15 , 11 , 4 }, + { 0 , 8 , 10 , 13 , 0 , 12 , 2 , 13 , 14 }}, + {{ 0 , 1 , 14 , 14 , 3 , 1 , 15 , 14 , 4 }, + { 0 , 4 , 7 , 9 , 5 , 12 , 2 , 7 , 8 }, + { 0 , 8 , 11 , 9 , 0 , 11 , 5 , 13 , 1 }, + { 0 , 2 , 1 , 0 , 6 , 7 , 12 , 8 , 7 }}, + {{ 0 , 2 , 6 , 6 , 0 , 7 , 9 , 15 , 6 }, + { 0 , 14 , 15 , 3 , 6 , 4 , 7 , 4 , 10 }, + { 0 , 13 , 10 , 8 , 12 , 10 , 2 , 12 , 9 }, + { 0 , 4 , 3 , 6 , 10 , 1 , 9 , 1 , 4 }}, + {{ 0 , 15 , 11 , 3 , 6 , 10 , 2 , 0 , 15 }, + { 0 , 2 , 2 , 4 , 15 , 7 , 12 , 9 , 3 }, + { 0 , 6 , 4 , 15 , 11 , 13 , 8 , 3 , 12 }, + { 0 , 9 , 15 , 9 , 1 , 14 , 5 , 4 , 10 }}, + {{ 0 , 11 , 3 , 15 , 9 , 11 , 6 , 8 , 11 }, + { 0 , 13 , 8 , 6 , 0 , 13 , 9 , 1 , 7 }, + { 0 , 2 , 13 , 3 , 7 , 7 , 12 , 7 , 14 }, + { 0 , 1 , 4 , 8 , 13 , 2 , 15 , 10 , 8 }}, + {{ 0 , 8 , 4 , 5 , 10 , 6 , 8 , 13 , 1 }, + { 0 , 1 , 14 , 10 , 3 , 1 , 5 , 10 , 4 }, + { 0 , 11 , 1 , 0 , 13 , 8 , 3 , 14 , 2 }, + { 0 , 7 , 2 , 7 , 8 , 13 , 10 , 7 , 13 }}, + {{ 0 , 3 , 9 , 1 , 1 , 8 , 0 , 3 , 10 }, + { 0 , 10 , 12 , 2 , 4 , 5 , 6 , 14 , 12 }, + { 0 , 15 , 5 , 11 , 15 , 15 , 7 , 10 , 0 }, + { 0 , 5 , 11 , 4 , 9 , 6 , 11 , 9 , 15 }}, + {{ 0 , 10 , 7 , 13 , 2 , 5 , 13 , 12 , 9 }, + { 0 , 6 , 0 , 8 , 7 , 0 , 1 , 3 , 5 }, + { 0 , 12 , 8 , 1 , 1 , 9 , 0 , 15 , 6 }, + { 0 , 11 , 6 , 15 , 4 , 15 , 14 , 5 , 12 }}, + {{ 0 , 6 , 2 , 12 , 8 , 3 , 3 , 9 , 3 }, + { 0 , 12 , 1 , 5 , 2 , 15 , 13 , 5 , 6 }, + { 0 , 9 , 12 , 2 , 3 , 12 , 4 , 6 , 10 }, + { 0 , 3 , 7 , 14 , 5 , 0 , 1 , 0 , 9 }}, + {{ 0 , 12 , 13 , 7 , 5 , 15 , 4 , 7 , 14 }, + { 0 , 11 , 10 , 14 , 12 , 10 , 14 , 12 , 11 }, + { 0 , 7 , 6 , 12 , 14 , 5 , 10 , 8 , 13 }, + { 0 , 14 , 12 , 3 , 11 , 9 , 7 , 15 , 0 }}, + {{ 0 , 5 , 12 , 11 , 11 , 13 , 14 , 5 , 5 }, + { 0 , 9 , 6 , 12 , 1 , 3 , 0 , 2 , 0 }, + { 0 , 3 , 9 , 5 , 5 , 6 , 1 , 0 , 15 }, + { 0 , 10 , 0 , 11 , 12 , 10 , 6 , 14 , 3 }}, + {{ 0 , 9 , 0 , 4 , 12 , 0 , 7 , 10 , 0 }, + { 0 , 5 , 9 , 11 , 10 , 9 , 11 , 15 , 14 }, + { 0 , 10 , 3 , 10 , 2 , 3 , 13 , 5 , 3 }, + { 0 , 0 , 5 , 5 , 7 , 4 , 0 , 2 , 5 }}, + {{ 0 , 0 , 5 , 2 , 4 , 14 , 5 , 6 , 12 }, + { 0 , 3 , 11 , 15 , 14 , 8 , 3 , 8 , 9 }, + { 0 , 5 , 2 , 14 , 8 , 0 , 11 , 9 , 5 }, + { 0 , 6 , 14 , 2 , 2 , 5 , 8 , 3 , 6 }}, + {{ 0 , 7 , 10 , 8 , 15 , 9 , 11 , 1 , 7 }, + { 0 , 8 , 5 , 1 , 9 , 6 , 8 , 6 , 2 }, + { 0 , 0 , 15 , 7 , 4 , 14 , 6 , 2 , 8 }, + { 0 , 13 , 9 , 12 , 14 , 3 , 13 , 12 , 11 }}}; + + volatile char ibin[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; + ndes_great ie; + unsigned long itmp, ietmp1, ietmp2; + char iec[9]; + int irow, icol, iss, l, m; + int volatile j, jj; + unsigned long *p; + + p = ndes_bit; + ie.r = ie.c = ie.l = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( j = 16, l = 32, m = 48; j >= 1; j--, l--, m-- ) { + ie.r = ( ie.r << 1 ) | ( p[iet[j]] & ir ? 1 : 0 ); + ie.c = ( ie.c << 1 ) | ( p[iet[l]] & ir ? 1 : 0 ); + ie.l = ( ie.l << 1 ) | ( p[iet[m]] & ir ? 1 : 0 ); + } + ie.r ^= k.r; + ie.c ^= k.c; + ie.l ^= k.l; + ietmp1 = ( ( unsigned long ) ie.c << 16 ) + ( unsigned long ) ie.r; + ietmp2 = ( ( unsigned long ) ie.l << 8 ) + ( ( unsigned long ) ie.c >> 8 ); + + _Pragma( "loopbound min 4 max 4" ) + for ( j = 1, m = 5; j <= 4; j++, m++ ) { + iec[j] = ietmp1 & 0x3fL; + iec[m] = ietmp2 & 0x3fL; + ietmp1 >>= 6; + ietmp2 >>= 6; + } + + itmp = 0L; + + _Pragma( "loopbound min 8 max 8" ) + for ( jj = 8; jj >= 1; jj-- ) { + j = iec[jj]; + irow = ( ( j & 0x1 ) << 1 ) + ( ( j & 0x20 ) >> 5 ); + icol = ( ( j & 0x2 ) << 2 ) + ( j & 0x4 ) + + ( ( j & 0x8 ) >> 2 ) + ( ( j & 0x10 ) >> 4 ); + iss = is[icol][irow][jj]; + itmp = ( itmp << 4 ) | ibin[iss]; + } + + *iout = 0L; + p = ndes_bit; + + _Pragma( "loopbound min 32 max 32" ) + for ( j = 32; j >= 1; j-- ) + *iout = ( *iout << 1 ); + *iout |= ( p[ipp[j]] & itmp ? 1 : 0 ); +} + +unsigned long ndes_getbit( ndes_immense source, int bitno, int nbits ) +{ + if ( bitno <= nbits ) + return ndes_bit[bitno] & source.r ? 1L : 0L; + else + return ndes_bit[bitno - nbits] & source.l ? 1L : 0L; +} + +void ndes_ks( /*ndes_immense key, */int n, ndes_great *kn ) +{ + int i, j, k, l; + + if ( n == 1 || n == 2 || n == 9 || n == 16 ) { + ndes_icd.r = ( ndes_icd.r | ( ( ndes_icd.r & 1L ) << 28 ) ) >> 1; + ndes_icd.l = ( ndes_icd.l | ( ( ndes_icd.l & 1L ) << 28 ) ) >> 1; + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( i = 1; i <= 2; i++ ) { + ndes_icd.r = ( ndes_icd.r | ( ( ndes_icd.r & 1L ) << 28 ) ) >> 1; + ndes_icd.l = ( ndes_icd.l | ( ( ndes_icd.l & 1L ) << 28 ) ) >> 1; + } + } + + ( *kn ).r = ( *kn ).c = ( *kn ).l = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( j = 16, k = 32, l = 48; j >= 1; j--, k--, l-- ) { + ( *kn ).r = ( *kn ).r << 1; + ( *kn ).r = ( ( *kn ).r ) | ( unsigned short ) + ndes_getbit( ndes_icd, ndes_ipc2[j], 28 ); + ( *kn ).c = ( *kn ).c << 1; + ( *kn ).c = ( ( *kn ).c ) | ( unsigned short ) + ndes_getbit( ndes_icd, ndes_ipc2[k], 28 ); + ( *kn ).l = ( *kn ).l << 1; + ( *kn ).l = ( ( *kn ).l ) | ( unsigned short ) + ndes_getbit( ndes_icd, ndes_ipc2[l], 28 ); + } +} + +int ndes_return() +{ + return (ndes_icd.r+ndes_icd.l + (-8390656) ) != 0 ; +} + +void _Pragma( "entrypoint" ) ndes_main() +{ + ndes_des( ndes_inp, ndes_key, &ndes_newkey, ndes_isw, &ndes_out ); +} + +/* main function */ + +int main( int argc, char **argv ) +{ + SET_UP + for(jobsComplete=-1; jobsComplete petrinet_main_iters_dummy_i + - main_min_dummy_i -> petrinet_main_min_dummy_i + - main_max_dummy_i -> petrinet_main_max_dummy_i + - P1_is_marked -> petrinet_P1_is_marked + - P1_marking_member_0 -> petrinet_P1_marking_member_0 + - P2_is_marked -> petrinet_P2_is_marked + - P2_marking_member_0 -> petrinet_P2_marking_member_0 + - P3_is_marked -> petrinet_P3_is_marked + - P3_marking_member_0 -> petrinet_P3_marking_member_0 +- Renamed main function to petrinet_main, set as entrypoint. +- Implemented new function main according to TACLeBench guidelines. +- Implemented function petrinet_return, calculates checksum over + petrinet_P3_marking_member_0. +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: bs_) followed by lowercase letter (e.g., bs_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - Operators within expressions shall be preceded and followed by one + whitespace + +2016-04-05: +- Return '0' on success + +2016-04-06: +- Fixed generation of return value + +2016-06-01: +- Changed all prefixes to lower-case + +2016-06-08: +- Prefix +- removed return from petrinet_main + +2016-06-13: +- introduced function petrinet_init diff --git a/all_pairs/source/petrinet/petrinet.c b/all_pairs/source/petrinet/petrinet.c new file mode 100644 index 0000000..7c9e1a0 --- /dev/null +++ b/all_pairs/source/petrinet/petrinet.c @@ -0,0 +1,990 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: Petrinet + + Author: Friedhelm Stappert, C-LAB, Paderborn, Germany + + Function: Simulate an extended Petri Net + Automatically generated code containing large amounts of + if-statements (more than 250) + + Source: Mälardalen benchmark suite + + Changes: no major functional changes + + License: may be used, modified, and re-distributed freely + +*/ + +/* Remove the following #define for actual WCET analyses! */ +/* + #define PROFILING +*/ + + +#include "../extra.h" + +#ifdef PROFILING +#include +#endif + +#ifdef PROFILING +/* Profiling variables. Remove for actual WCET analyses. */ +int petrinet_main_iters_dummy_i = 0, + petrinet_main_min_dummy_i = 100000, + petrinet_main_max_dummy_i = 0; +#endif + +/* + Forward declaration of functions +*/ +void petrinet_init( void ); +int petrinet_return( void ); +void petrinet_main( void ); +//int main( void ); + + +volatile int petrinet_P1_is_marked; +volatile long petrinet_P1_marking_member_0[ 3 ]; +volatile int petrinet_P2_is_marked; +volatile long petrinet_P2_marking_member_0[ 5 ]; +volatile int petrinet_P3_is_marked; +volatile long petrinet_P3_marking_member_0[ 6 ]; + +const long petrinet_CHECKSUM = 0; + +void _Pragma ( "entrypoint" ) petrinet_main( void ) +{ + int dummy_i; + /* dummy_i = 17; Takes too much time */ + dummy_i = 2; + + #ifdef PROFILING + main_iters_dummy_i = 0; + #endif + _Pragma( "loopbound min 2 max 2" ) + while ( dummy_i > 0 ) { + #ifdef PROFILING + main_iters_dummy_i++; + #endif + + dummy_i--; + /* Permutation for Place P1 : 0, 1, 2 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 1 ] + == petrinet_P1_marking_member_0[ 2 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 0 ]; + y = petrinet_P1_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( x < y ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 0, 2, 1 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 2 ] + == petrinet_P1_marking_member_0[ 1 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 0 ]; + y = petrinet_P1_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 1, 0, 2 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 0 ] + == petrinet_P1_marking_member_0[ 2 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 1 ]; + y = petrinet_P1_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( x < y ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 1, 2, 0 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 2 ] + == petrinet_P1_marking_member_0[ 0 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 1 ]; + y = petrinet_P1_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 2, 0, 1 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 0 ] + == petrinet_P1_marking_member_0[ 1 ] ) ) { + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 2 ]; + y = petrinet_P1_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 2, 1, 0 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 1 ] + == petrinet_P1_marking_member_0[ 0 ] ) ) { + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 2 ]; + y = petrinet_P1_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place P2 : 0, 1, 2, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( ( petrinet_P3_is_marked + 3 ) <= 6 ) ) && + ( ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 1, 3, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( ( petrinet_P3_is_marked + 3 ) <= 6 ) ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 2, 1, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 2, 3, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 3, 1, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 3, 2, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 0, 2, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 0, 3, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 2, 0, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 2, 3, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 3, 0, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + + /* Permutation for Place petrinet_P2 : 1, 3, 2, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + + /* Permutation for Place petrinet_P2 : 2, 0, 1, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 0, 3, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 1, 0, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 1, 3, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 3, 0, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 3, 1, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 3, 0, 1, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 3 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + + /* Permutation for Place petrinet_P2 : 3, 0, 2, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 3 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + } + #ifdef PROFILING + if ( main_iters_dummy_i < main_min_dummy_i ) + main_min_dummy_i = main_iters_dummy_i; + if ( main_iters_dummy_i > main_max_dummy_i ) + main_max_dummy_i = main_iters_dummy_i; + #endif + + #ifdef PROFILING + printf( "main::dummy_i-loop: [%d, %d]\n", + main_min_dummy_i, main_max_dummy_i ); + #endif + + //dummy_i = 77; + // TODO: not a good return value + //return dummy_i; +} + + +void petrinet_init( void ) +{ + petrinet_P1_is_marked = 3; + petrinet_P2_is_marked = 5; + petrinet_P3_is_marked = 0; + + /* + Maybe we should also initialise these arrays, as they may be read + in the petrinet_main() function before being written. + */ + /* + volatile long petrinet_P1_marking_member_0[ 3 ]; + volatile long petrinet_P2_marking_member_0[ 5 ]; + volatile long petrinet_P3_marking_member_0[ 6 ]; + */ +} + + +int petrinet_return( void ) +{ + // TODO: use something from the Px_... arrays + int checksum = 0; + int i; + + for ( i = 0; i < 3; ++i ) + checksum += petrinet_P1_marking_member_0[i]; + + for ( i = 0; i < 5; ++i ) + checksum += petrinet_P2_marking_member_0[i]; + + for ( i = 0; i < 6; ++i ) + checksum += petrinet_P3_marking_member_0[i]; + + return ( ( checksum == petrinet_CHECKSUM ) ? 0 : -1 ); +} + + +int main( int argc, char **argv ) +{ + SET_UP + + for (jobsComplete=-1; jobsComplete, Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of 128, + bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. +*/ + +#include "aes.h" + +#include "aestab.h" + +#define four_tables(x,tab,vf,rf,c) ( tab[0][bval(vf(x,0,c),rf(0,c))] ^ \ + tab[1][bval(vf(x,1,c),rf(1,c))] ^ \ + tab[2][bval(vf(x,2,c),rf(2,c))] ^ \ + tab[3][bval(vf(x,3,c),rf(3,c))] ) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((r-c)&3) + +#define ls_box(x,c) four_tables(x,rijndael_dec_fl_tab,vf1,rf2,c) + +#define inv_mcol(x) four_tables(x,rijndael_dec_im_tab,vf1,rf1,0) + +/* + Subroutine to set the block size (if variable) in bytes, legal + values being 16, 24 and 32. +*/ + +#define nc (Ncol) + +/* + Initialise the key schedule from the user supplied key. The key + length is now specified in bytes - 16, 24 or 32 as appropriate. + This corresponds to bit lengths of 128, 192 and 256 bits, and + to Nk values of 4, 6 and 8 respectively. +*/ + +#define mx(t,f) (*t++ = inv_mcol(*f),f++) +#define cp(t,f) *t++ = *f++ + +#define cpy(d,s) do { cp(d,s); cp(d,s); cp(d,s); cp(d,s); } while (0) +#define mix(d,s) do { mx(d,s); mx(d,s); mx(d,s); mx(d,s); } while (0) + +aes_ret rijndael_dec_set_key( byte in_key[], const word n_bytes, + const enum aes_key f, struct aes *cx ) +{ + word *kf, *kt, rci; + + if ( ( n_bytes & 7 ) || n_bytes < 16 || n_bytes > 32 || ( !( f & 1 ) && + !( f & 2 ) ) ) + return ( n_bytes ? cx->mode &= ~0x03, aes_bad : ( aes_ret )( cx->Nkey << 2 ) ); + + cx->mode = ( cx->mode & ~0x03 ) | ( ( byte )f & 0x03 ); + cx->Nkey = n_bytes >> 2; + cx->Nrnd = Nr( cx->Nkey, ( word )nc ); + + cx->e_key[0] = word_in( in_key ); + cx->e_key[1] = word_in( in_key + 4 ); + cx->e_key[2] = word_in( in_key + 8 ); + cx->e_key[3] = word_in( in_key + 12 ); + + kf = cx->e_key; + kt = kf + nc * ( cx->Nrnd + 1 ) - cx->Nkey; + rci = 0; + + switch ( cx->Nkey ) { + case 4: + _Pragma( "loopbound min 0 max 0" ) + do { + kf[4] = kf[0] ^ ls_box( kf[3], 3 ) ^ rijndael_dec_rcon_tab[rci++]; + kf[5] = kf[1] ^ kf[4]; + kf[6] = kf[2] ^ kf[5]; + kf[7] = kf[3] ^ kf[6]; + kf += 4; + } while ( kf < kt ); + break; + + case 6: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + _Pragma( "loopbound min 0 max 0" ) + do { + kf[ 6] = kf[0] ^ ls_box( kf[5], 3 ) ^ rijndael_dec_rcon_tab[rci++]; + kf[ 7] = kf[1] ^ kf[ 6]; + kf[ 8] = kf[2] ^ kf[ 7]; + kf[ 9] = kf[3] ^ kf[ 8]; + kf[10] = kf[4] ^ kf[ 9]; + kf[11] = kf[5] ^ kf[10]; + kf += 6; + } while ( kf < kt ); + break; + + case 8: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + cx->e_key[6] = word_in( in_key + 24 ); + cx->e_key[7] = word_in( in_key + 28 ); + _Pragma( "loopbound min 7 max 7" ) + do { + kf[ 8] = kf[0] ^ ls_box( kf[7], 3 ) ^ rijndael_dec_rcon_tab[rci++]; + kf[ 9] = kf[1] ^ kf[ 8]; + kf[10] = kf[2] ^ kf[ 9]; + kf[11] = kf[3] ^ kf[10]; + kf[12] = kf[4] ^ ls_box( kf[11], 0 ); + kf[13] = kf[5] ^ kf[12]; + kf[14] = kf[6] ^ kf[13]; + kf[15] = kf[7] ^ kf[14]; + kf += 8; + } while ( kf < kt ); + break; + } + + if ( ( cx->mode & 3 ) != enc ) { + word i; + + kt = cx->d_key + nc * cx->Nrnd; + kf = cx->e_key; + + cpy( kt, kf ); + kt -= 2 * nc; + + _Pragma( "loopbound min 0 max 0" ) + for ( i = 1; i < cx->Nrnd; ++i ) { + mix( kt, kf ); + kt -= 2 * nc; + } + + cpy( kt, kf ); + } + + return aes_good; +} + +short rijndael_dec_decrypt( const unsigned char in_blk[], + unsigned char out_blk[], const struct aes *cx ) +{ + const unsigned long *kp = cx->d_key; + if ( !( cx->mode & 2 ) ) + return 0; + unsigned long b0[4]; + b0[0] = *( unsigned long * )in_blk ^ kp[0]; + b0[1] = *( unsigned long * )( in_blk + 4 )^kp[1]; + b0[2] = *( unsigned long * )( in_blk + 8 )^kp[2]; + b0[3] = *( unsigned long * )( in_blk + 12 )^kp[3]; + kp += 4; + unsigned long b1[4]; + switch ( cx->Nrnd ) { + case 14: + b1[0] = kp[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + kp += 8; + case 12: + b1[0] = kp[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + kp += 8; + case 10: + b1[0] = kp[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 8 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 8 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 8 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 8 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 12 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 12 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 12 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 12 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 16 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 16 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 16 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 16 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 20 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 20 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 20 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 20 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 24 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 24 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 24 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 24 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 28 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 28 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 28 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 28 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 32 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 32 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 32 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 32 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 36 )[0] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 36 )[1] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 36 )[2] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 36 )[3] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + } + *( unsigned long * )out_blk = ( b0[0] ); + *( unsigned long * )( out_blk + 4 ) = ( b0[1] ); + *( unsigned long * )( out_blk + 8 ) = ( b0[2] ); + *( unsigned long * )( out_blk + 12 ) = ( b0[3] ); + return aes_good; +} + diff --git a/all_pairs/source/rijndael_dec/aes.h b/all_pairs/source/rijndael_dec/aes.h new file mode 100644 index 0000000..69bf3d3 --- /dev/null +++ b/all_pairs/source/rijndael_dec/aes.h @@ -0,0 +1,165 @@ +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + 1. FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of + 128 bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. + + 2. THE CIPHER INTERFACE + + byte (an unsigned 8-bit type) + word (an unsigned 32-bit type) + aes_ret: (a signed 16 bit type for function return values) + aes_good (value != 0, a good return) + aes_bad (value == 0, an error return) + enum aes_key: (encryption direction) + enc (set key for encryption) + dec (set key for decryption) + both (set key for both) + class or struct aes (structure for context) + + C subroutine calls: + + aes_ret set_blk(const word block_length, aes *cx) (variable block size) + aes_ret set_key(const byte key[], const word key_length, + const enum aes_key direction, aes *cx) + aes_ret encrypt(const byte input_blk[], byte output_blk[], const aes *cx) + aes_ret decrypt(const byte input_blk[], byte output_blk[], const aes *cx) + + IMPORTANT NOTE: If you are using this C interface and your compiler does + not set the memory used for objects to zero before use, you will need to + ensure that cx.mode is set to zero before using the C subroutine calls. + + The block length inputs to set_block and set_key are in numbers of + BYTES, not bits. The calls to subroutines must be made in the above + order but multiple calls can be made without repeating earlier calls + if their parameters have not changed. If the cipher block length is + variable but set_blk has not been called before cipher operations a + value of 16 is assumed (that is, the AES block size). In contrast to + earlier versions the block and key length parameters are now checked + for correctness and the encryption and decryption routines check to + ensure that an appropriate key has been set before they are called. + +*/ + +#ifndef _AES_H +#define _AES_H + +/* The only supported block size for the benchmark is 16 */ +#define BLOCK_SIZE 16 + +/* + The number of key schedule words for different block and key lengths + (allowing for the method of computation which requires the length to + be a multiple of the key length): + + Key Schedule key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 44 60 54 56 64 + length 20 | 60 60 66 70 80 + (bytes) 24 | 80 80 78 84 96 + 28 | 100 100 102 98 112 + 32 | 120 120 120 126 120 + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + The following values assume that the key length will be variable and may + be of maximum length (32 bytes). + + Nk = number_of_key_bytes / 4 + Nc = number_of_columns_in_state / 4 + Nr = number of encryption/decryption rounds + Rc = number of elements in rcon table + Ks = number of 32-bit words in key schedule +*/ + +#define Nr(Nk,Nc) ((Nk > Nc ? Nk : Nc) + 6) +#define Rc(Nk,Nc) ((Nb * (Nr(Nk,Nc) + 1) - 1) / Nk) +#define Ks(Nk,Nc) (Nk * (Rc(Nk,Nc) + 1)) + +#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11) +#define KS_LENGTH 4 * BLOCK_SIZE + +/* End of configuration options, but see also aes.c */ + +typedef unsigned char byte; /* must be an 8-bit storage unit */ +typedef unsigned long word; /* must be a 32-bit storage unit */ +typedef short aes_ret; /* function return value */ + +#define aes_bad 0 +#define aes_good 1 + +/* + upr(x,n): rotates bytes within words by n positions, moving bytes + to higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word +*/ + +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) +#define ups(x,n) ((x) << 8 * (n)) +#define bval(x,n) ((byte)((x) >> 8 * (n))) +#define byte_swap(x) (upr(x,1) & 0x00ff00ff | upr(x,3) & 0xff00ff00) +#define bytes2word(b0, b1, b2, b3) ((word)(b3) << 24 | (word)(b2) << 16 | \ + (word)(b1) << 8 | (b0)) + +#define word_in(x) *(word*)(x) +#define word_out(x,v) *(word*)(x) = (v) + +enum aes_const { Nrow = 4, /* the number of rows in the cipher state */ + Mcol = 8, /* maximum number of columns in the state */ + Ncol = BLOCK_SIZE / 4, + Shr0 = 0, /* the cyclic shift values for rows 0, 1, 2 & 3 */ + Shr1 = 1, + Shr2 = BLOCK_SIZE == 32 ? 3 : 2, + Shr3 = BLOCK_SIZE == 32 ? 4 : 3 + }; + +enum aes_key { enc = 1, /* set if encryption is needed */ + dec = 2, /* set if decryption is needed */ + both = 3 /* set if both are needed */ + }; + +struct aes { + word Nkey; /* the number of words in the key input block */ + word Nrnd; /* the number of cipher rounds */ + word e_key[KS_LENGTH]; /* the encryption key schedule */ + word d_key[KS_LENGTH]; /* the decryption key schedule */ + byte mode; /* encrypt, decrypt or both */ +}; + +aes_ret rijndael_dec_set_key( byte key[], const word n_bytes, + const enum aes_key f, struct aes *cx ); +aes_ret rijndael_dec_decrypt( const byte in_blk[], byte out_blk[], + const struct aes *cx ); + +#endif diff --git a/all_pairs/source/rijndael_dec/aestab.h b/all_pairs/source/rijndael_dec/aestab.h new file mode 100644 index 0000000..c42702b --- /dev/null +++ b/all_pairs/source/rijndael_dec/aestab.h @@ -0,0 +1,379 @@ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +/* + Used to ensure table is generated in the right format + depending on the internal byte order required. +*/ + +#define w0(p) 0x000000##p + +/* + Number of elements required in this table for different + block and key lengths is: + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + this table can be a table of bytes if the key schedule + code is adjusted accordingly +*/ + +const word rijndael_dec_rcon_tab[29] = { + w0( 01 ), w0( 02 ), w0( 04 ), w0( 08 ), + w0( 10 ), w0( 20 ), w0( 40 ), w0( 80 ), + w0( 1b ), w0( 36 ), w0( 6c ), w0( d8 ), + w0( ab ), w0( 4d ), w0( 9a ), w0( 2f ), + w0( 5e ), w0( bc ), w0( 63 ), w0( c6 ), + w0( 97 ), w0( 35 ), w0( 6a ), w0( d4 ), + w0( b3 ), w0( 7d ), w0( fa ), w0( ef ), + w0( c5 ) +}; + +#undef w0 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +#define r0(p,q,r,s) 0x##p##q##r##s +#define r1(p,q,r,s) 0x##q##r##s##p +#define r2(p,q,r,s) 0x##r##s##p##q +#define r3(p,q,r,s) 0x##s##p##q##r +#define w0(p) 0x000000##p +#define w1(p) 0x0000##p##00 +#define w2(p) 0x00##p##0000 +#define w3(p) 0x##p##000000 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +/* data for forward tables (other than last round) */ + +#define f_table \ + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6), \ + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91), \ + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56), \ + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec), \ + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa), \ + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb), \ + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45), \ + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b), \ + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c), \ + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83), \ + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9), \ + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a), \ + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d), \ + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f), \ + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df), \ + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea), \ + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34), \ + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b), \ + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d), \ + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13), \ + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1), \ + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6), \ + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72), \ + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85), \ + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed), \ + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11), \ + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe), \ + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b), \ + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05), \ + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1), \ + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42), \ + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf), \ + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3), \ + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e), \ + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a), \ + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6), \ + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3), \ + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b), \ + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28), \ + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad), \ + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14), \ + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8), \ + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4), \ + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2), \ + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da), \ + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49), \ + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf), \ + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10), \ + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c), \ + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97), \ + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e), \ + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f), \ + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc), \ + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c), \ + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69), \ + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27), \ + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22), \ + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33), \ + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9), \ + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5), \ + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a), \ + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0), \ + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e), \ + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) + +/* data for inverse tables (other than last round) */ + +#define i_table \ + r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a), \ + r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b), \ + r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5), \ + r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5), \ + r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d), \ + r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b), \ + r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95), \ + r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e), \ + r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27), \ + r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d), \ + r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62), \ + r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9), \ + r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52), \ + r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66), \ + r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3), \ + r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed), \ + r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e), \ + r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4), \ + r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4), \ + r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd), \ + r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d), \ + r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60), \ + r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67), \ + r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79), \ + r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00), \ + r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c), \ + r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36), \ + r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24), \ + r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b), \ + r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c), \ + r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12), \ + r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14), \ + r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3), \ + r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b), \ + r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8), \ + r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84), \ + r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7), \ + r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77), \ + r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47), \ + r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22), \ + r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98), \ + r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f), \ + r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54), \ + r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82), \ + r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf), \ + r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db), \ + r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83), \ + r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef), \ + r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29), \ + r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35), \ + r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33), \ + r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17), \ + r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4), \ + r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46), \ + r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb), \ + r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d), \ + r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb), \ + r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a), \ + r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73), \ + r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78), \ + r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2), \ + r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff), \ + r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64), \ + r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0) + +/* generate the required tables in the desired endian format */ + +#undef r +#define r r0 +const word rijndael_dec_it_tab[4][256] = { + { i_table }, +#undef r +#define r r1 + { i_table }, +#undef r +#define r r2 + { i_table }, +#undef r +#define r r3 + { i_table } +}; + +/* data for inverse tables (last round) */ + +#define li_table \ + w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38), \ + w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb), \ + w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87), \ + w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb), \ + w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d), \ + w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e), \ + w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2), \ + w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25), \ + w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16), \ + w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92), \ + w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da), \ + w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84), \ + w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a), \ + w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06), \ + w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02), \ + w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b), \ + w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea), \ + w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73), \ + w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85), \ + w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e), \ + w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89), \ + w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b), \ + w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20), \ + w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4), \ + w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31), \ + w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f), \ + w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d), \ + w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef), \ + w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0), \ + w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61), \ + w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26), \ + w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d), + +/* generate the required tables in the desired endian format */ + +#undef r +#define r(p,q,r,s) w0(q) +const word rijndael_dec_fl_tab[4][256] = { + { f_table }, +#undef r +#define r(p,q,r,s) w1(q) + { f_table }, +#undef r +#define r(p,q,r,s) w2(q) + { f_table }, +#undef r +#define r(p,q,r,s) w3(q) + { f_table } +}; + +#undef w +#define w w0 +const word rijndael_dec_il_tab[4][256] = { + { li_table }, +#undef w +#define w w1 + { li_table }, +#undef w +#define w w2 + { li_table }, +#undef w +#define w w3 + { li_table } +}; + +#define m_table \ + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12), \ + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a), \ + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62), \ + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a), \ + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2), \ + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca), \ + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82), \ + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba), \ + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9), \ + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1), \ + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9), \ + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81), \ + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29), \ + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11), \ + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59), \ + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61), \ + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf), \ + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87), \ + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf), \ + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7), \ + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f), \ + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67), \ + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f), \ + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17), \ + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64), \ + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c), \ + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14), \ + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c), \ + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84), \ + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc), \ + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4), \ + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc), \ + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53), \ + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b), \ + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23), \ + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b), \ + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3), \ + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b), \ + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3), \ + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb), \ + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88), \ + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0), \ + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8), \ + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0), \ + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68), \ + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50), \ + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18), \ + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20), \ + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe), \ + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6), \ + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e), \ + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6), \ + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e), \ + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26), \ + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e), \ + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56), \ + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25), \ + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d), \ + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55), \ + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d), \ + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5), \ + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd), \ + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5), \ + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d) + +#undef r +#define r r0 + +const word rijndael_dec_im_tab[4][256] = { + { m_table }, +#undef r +#define r r1 + { m_table }, +#undef r +#define r r2 + { m_table }, +#undef r +#define r r3 + { m_table } +}; diff --git a/all_pairs/source/rijndael_dec/input_small_enc.c b/all_pairs/source/rijndael_dec/input_small_enc.c new file mode 100644 index 0000000..2a881a9 --- /dev/null +++ b/all_pairs/source/rijndael_dec/input_small_enc.c @@ -0,0 +1,2051 @@ +unsigned char rijndael_dec_data[] = { + 96, 83, 127, 28, 212, 92, 146, 102, 38, 17, 193, 142, 95, 217, 184, 105, + 79, 112, 144, 112, 44, 202, 141, 48, 181, 177, 82, 92, 208, 250, 216, 152, + 41, 208, 7, 232, 238, 116, 134, 238, 230, 190, 239, 195, 235, 80, 125, 51, + 251, 39, 7, 100, 213, 190, 189, 81, 241, 49, 215, 254, 253, 203, 13, 164, + 175, 244, 25, 111, 226, 225, 176, 96, 58, 165, 32, 243, 68, 205, 209, 242, + 186, 229, 167, 155, 238, 105, 120, 173, 246, 72, 29, 96, 71, 169, 83, 154, + 226, 129, 236, 52, 243, 159, 61, 71, 20, 119, 245, 196, 25, 203, 11, 10, + 37, 163, 139, 180, 250, 191, 138, 99, 78, 192, 73, 186, 22, 12, 119, 151, + 185, 155, 195, 54, 73, 207, 108, 170, 112, 237, 100, 165, 219, 223, 23, 179, + 124, 172, 52, 22, 143, 57, 132, 60, 176, 218, 11, 86, 89, 59, 254, 84, + 180, 76, 120, 174, 17, 214, 88, 48, 240, 12, 56, 93, 136, 156, 75, 176, + 30, 43, 4, 107, 30, 210, 26, 183, 235, 39, 35, 205, 139, 80, 249, 182, + 15, 91, 210, 234, 47, 67, 64, 234, 148, 108, 240, 242, 32, 11, 48, 199, + 117, 31, 149, 30, 97, 149, 241, 50, 177, 166, 127, 31, 135, 115, 240, 77, + 198, 88, 108, 246, 108, 148, 158, 89, 173, 233, 252, 95, 51, 42, 218, 54, + 28, 143, 203, 164, 74, 147, 55, 108, 225, 222, 87, 161, 243, 35, 179, 130, + 29, 70, 225, 178, 148, 152, 247, 167, 21, 245, 84, 139, 3, 228, 221, 25, + 53, 36, 121, 29, 204, 35, 1, 46, 26, 8, 237, 102, 231, 252, 176, 88, + 24, 110, 255, 163, 86, 64, 117, 68, 178, 73, 219, 201, 24, 155, 76, 255, + 253, 199, 165, 95, 246, 179, 15, 47, 203, 81, 92, 231, 246, 247, 111, 58, + 82, 222, 193, 24, 37, 164, 161, 8, 169, 172, 223, 111, 186, 72, 160, 116, + 242, 8, 192, 178, 224, 177, 228, 42, 102, 206, 237, 52, 143, 16, 150, 143, + 108, 3, 88, 81, 199, 49, 110, 220, 5, 89, 244, 227, 27, 226, 101, 9, + 238, 0, 206, 228, 254, 19, 189, 240, 159, 29, 46, 2, 206, 184, 205, 228, + 144, 241, 88, 78, 156, 23, 44, 200, 99, 146, 179, 96, 1, 143, 87, 57, + 39, 75, 174, 32, 190, 125, 152, 183, 46, 39, 136, 88, 240, 110, 104, 70, + 253, 29, 110, 113, 235, 123, 56, 60, 243, 238, 246, 113, 11, 18, 246, 108, + 95, 238, 177, 43, 3, 112, 121, 161, 196, 204, 211, 171, 197, 41, 249, 71, + 194, 153, 82, 28, 10, 28, 12, 241, 212, 90, 124, 236, 171, 54, 35, 226, + 152, 246, 241, 74, 139, 133, 241, 76, 183, 197, 232, 250, 54, 202, 11, 10, + 203, 30, 169, 138, 110, 252, 62, 172, 6, 241, 81, 181, 87, 177, 128, 221, + 111, 133, 94, 251, 184, 54, 92, 242, 28, 112, 138, 116, 32, 164, 158, 59, + 51, 30, 155, 126, 196, 117, 233, 117, 92, 74, 4, 72, 19, 237, 248, 142, + 184, 175, 126, 203, 4, 210, 70, 40, 105, 16, 36, 42, 118, 110, 4, 180, + 208, 52, 232, 230, 107, 154, 233, 61, 176, 170, 32, 59, 60, 47, 43, 70, + 71, 3, 58, 24, 166, 22, 165, 154, 255, 166, 12, 81, 63, 116, 146, 12, + 5, 6, 133, 240, 110, 253, 209, 15, 71, 179, 93, 203, 58, 138, 5, 90, + 111, 140, 19, 186, 191, 68, 230, 121, 95, 166, 219, 107, 233, 156, 18, 145, + 239, 150, 234, 191, 91, 233, 114, 5, 215, 85, 30, 66, 33, 152, 117, 128, + 236, 189, 201, 203, 10, 184, 198, 249, 61, 27, 144, 102, 246, 191, 54, 129, + 86, 8, 197, 98, 231, 234, 222, 164, 161, 40, 150, 253, 208, 82, 92, 225, + 85, 206, 59, 1, 170, 5, 255, 219, 89, 204, 122, 169, 78, 8, 5, 70, + 75, 128, 80, 176, 16, 214, 253, 176, 255, 191, 91, 89, 126, 155, 128, 195, + 56, 150, 101, 131, 255, 234, 241, 250, 61, 210, 85, 19, 21, 23, 122, 180, + 34, 100, 102, 166, 128, 21, 177, 11, 86, 110, 112, 179, 126, 36, 152, 196, + 62, 185, 186, 20, 91, 35, 85, 148, 168, 68, 145, 245, 170, 25, 190, 237, + 192, 125, 186, 182, 22, 188, 161, 122, 194, 21, 14, 102, 206, 60, 129, 156, + 173, 176, 37, 112, 129, 145, 177, 101, 206, 179, 35, 221, 107, 228, 181, 212, + 52, 253, 241, 145, 121, 128, 68, 118, 78, 66, 166, 78, 176, 62, 217, 243, + 193, 1, 254, 200, 35, 67, 226, 77, 55, 72, 6, 144, 22, 85, 252, 209, + 142, 65, 226, 158, 126, 168, 175, 179, 219, 116, 235, 227, 42, 49, 126, 126, + 215, 200, 126, 0, 39, 247, 161, 217, 26, 228, 232, 113, 53, 151, 34, 223, + 91, 242, 155, 156, 144, 229, 237, 127, 227, 49, 239, 71, 102, 115, 74, 135, + 103, 13, 3, 108, 101, 211, 36, 59, 146, 143, 230, 44, 212, 145, 229, 53, + 108, 175, 42, 131, 113, 123, 30, 28, 149, 153, 117, 233, 76, 33, 148, 110, + 19, 83, 125, 135, 44, 202, 2, 155, 4, 240, 167, 7, 13, 115, 243, 216, + 73, 248, 216, 82, 230, 153, 48, 234, 157, 2, 130, 99, 147, 2, 244, 19, + 125, 30, 39, 148, 49, 134, 140, 240, 128, 230, 171, 24, 53, 245, 54, 72, + 111, 230, 192, 165, 199, 47, 186, 238, 121, 95, 220, 76, 229, 253, 157, 47, + 34, 47, 39, 77, 199, 203, 163, 148, 172, 56, 204, 96, 69, 235, 215, 96, + 92, 139, 92, 49, 73, 228, 70, 221, 18, 84, 167, 179, 201, 239, 71, 64, + 29, 247, 84, 56, 148, 36, 169, 144, 192, 60, 153, 171, 89, 125, 48, 98, + 201, 56, 230, 154, 146, 46, 184, 202, 3, 39, 113, 90, 249, 163, 0, 188, + 233, 10, 216, 17, 159, 42, 134, 57, 70, 24, 33, 63, 8, 67, 85, 7, + 133, 180, 127, 12, 234, 121, 183, 38, 131, 154, 241, 236, 69, 67, 116, 54, + 40, 225, 6, 220, 22, 251, 1, 100, 110, 165, 114, 12, 170, 21, 190, 103, + 242, 171, 216, 66, 30, 3, 214, 137, 231, 172, 61, 8, 249, 198, 113, 181, + 171, 13, 159, 21, 147, 67, 249, 94, 189, 174, 15, 2, 62, 254, 29, 32, + 209, 169, 184, 119, 220, 98, 248, 163, 171, 22, 62, 125, 155, 100, 186, 97, + 163, 245, 70, 216, 246, 1, 11, 83, 41, 100, 64, 52, 99, 184, 151, 99, + 46, 100, 168, 158, 210, 150, 38, 231, 27, 255, 59, 141, 232, 127, 56, 39, + 194, 104, 178, 151, 15, 25, 219, 221, 81, 119, 178, 153, 94, 173, 64, 215, + 128, 132, 163, 159, 214, 254, 181, 194, 113, 144, 141, 103, 17, 108, 178, 59, + 62, 205, 117, 57, 183, 97, 18, 210, 87, 163, 231, 213, 233, 251, 94, 136, + 217, 168, 69, 48, 55, 68, 144, 203, 187, 51, 211, 151, 1, 194, 118, 181, + 154, 103, 186, 87, 43, 128, 215, 79, 101, 175, 60, 221, 158, 189, 94, 194, + 87, 73, 72, 162, 252, 26, 40, 142, 86, 228, 82, 255, 122, 192, 167, 78, + 177, 40, 249, 195, 100, 188, 31, 208, 124, 123, 31, 121, 244, 4, 82, 3, + 132, 15, 2, 29, 186, 76, 106, 109, 158, 114, 25, 212, 74, 64, 255, 43, + 40, 146, 159, 225, 39, 65, 85, 37, 60, 160, 123, 116, 127, 134, 45, 177, + 191, 49, 136, 211, 167, 218, 197, 15, 96, 45, 55, 11, 237, 103, 118, 207, + 0, 211, 25, 143, 19, 93, 114, 90, 105, 253, 88, 140, 207, 56, 150, 0, + 136, 159, 134, 63, 75, 142, 177, 0, 107, 105, 78, 148, 214, 248, 70, 72, + 125, 220, 156, 220, 222, 102, 202, 176, 12, 58, 24, 39, 254, 170, 130, 77, + 203, 193, 162, 56, 162, 57, 76, 153, 170, 112, 94, 0, 220, 58, 58, 40, + 173, 2, 193, 164, 168, 127, 225, 238, 10, 194, 112, 213, 181, 126, 222, 152, + 12, 57, 14, 146, 137, 154, 203, 179, 45, 133, 70, 204, 66, 249, 32, 136, + 145, 0, 221, 224, 10, 1, 202, 139, 145, 247, 72, 254, 32, 169, 121, 167, + 114, 198, 244, 251, 243, 8, 114, 188, 178, 173, 25, 243, 122, 220, 45, 98, + 7, 168, 66, 58, 225, 217, 152, 81, 89, 39, 167, 146, 181, 138, 253, 196, + 145, 4, 72, 9, 14, 137, 155, 32, 217, 64, 4, 173, 220, 66, 114, 21, + 137, 118, 87, 163, 217, 204, 74, 236, 45, 170, 60, 141, 216, 234, 182, 79, + 74, 73, 94, 63, 89, 134, 88, 64, 32, 241, 9, 114, 253, 164, 108, 31, + 27, 42, 172, 7, 102, 213, 153, 83, 1, 152, 136, 224, 248, 70, 112, 15, + 211, 194, 216, 16, 255, 62, 83, 147, 173, 192, 239, 55, 18, 223, 34, 152, + 25, 163, 229, 4, 55, 219, 235, 187, 51, 116, 12, 202, 198, 116, 188, 217, + 91, 30, 11, 9, 13, 222, 120, 16, 93, 99, 56, 129, 27, 133, 155, 120, + 124, 112, 101, 42, 222, 122, 124, 59, 84, 228, 202, 189, 13, 11, 10, 44, + 220, 97, 67, 53, 246, 47, 230, 131, 192, 1, 247, 137, 90, 77, 243, 131, + 2, 130, 93, 183, 117, 102, 69, 191, 27, 87, 103, 218, 157, 124, 17, 209, + 135, 92, 78, 211, 141, 25, 157, 53, 17, 249, 209, 206, 84, 19, 135, 253, + 57, 36, 38, 112, 184, 61, 76, 5, 203, 155, 7, 9, 179, 167, 38, 136, + 189, 40, 19, 183, 132, 81, 135, 167, 48, 74, 186, 249, 144, 193, 150, 73, + 10, 192, 191, 160, 74, 246, 12, 38, 107, 3, 66, 122, 184, 168, 218, 233, + 78, 216, 11, 57, 124, 104, 167, 0, 187, 2, 214, 136, 252, 60, 85, 128, + 128, 31, 70, 197, 211, 180, 216, 75, 212, 163, 168, 15, 174, 44, 194, 231, + 24, 181, 154, 161, 241, 95, 197, 227, 146, 195, 187, 69, 127, 154, 145, 176, + 180, 157, 13, 225, 107, 60, 29, 14, 223, 93, 214, 248, 107, 65, 168, 251, + 231, 46, 34, 203, 76, 20, 206, 125, 80, 25, 196, 60, 213, 51, 238, 73, + 17, 223, 151, 44, 60, 213, 164, 117, 188, 66, 195, 170, 190, 117, 110, 21, + 27, 78, 244, 124, 224, 142, 182, 10, 122, 135, 121, 143, 240, 124, 6, 8, + 22, 15, 3, 137, 12, 19, 11, 62, 212, 205, 3, 202, 189, 157, 141, 68, + 171, 142, 106, 69, 207, 8, 116, 194, 6, 200, 96, 220, 248, 132, 46, 171, + 57, 234, 31, 3, 112, 108, 15, 139, 243, 34, 181, 250, 10, 86, 71, 162, + 167, 85, 177, 57, 166, 80, 41, 253, 128, 28, 127, 220, 149, 27, 29, 41, + 201, 116, 211, 236, 34, 200, 100, 157, 130, 223, 4, 162, 108, 181, 40, 255, + 96, 18, 77, 36, 217, 17, 225, 142, 124, 17, 91, 227, 13, 224, 213, 37, + 115, 216, 93, 149, 103, 105, 152, 190, 207, 54, 74, 226, 78, 133, 200, 252, + 157, 152, 39, 0, 173, 168, 132, 142, 17, 66, 241, 137, 12, 106, 42, 81, + 239, 78, 31, 131, 49, 243, 122, 178, 212, 137, 160, 104, 15, 145, 15, 116, + 103, 141, 94, 40, 127, 180, 174, 96, 222, 182, 226, 168, 174, 113, 228, 156, + 10, 18, 231, 122, 150, 178, 17, 200, 254, 96, 42, 243, 225, 58, 235, 64, + 159, 73, 162, 72, 46, 160, 33, 191, 99, 73, 130, 32, 135, 84, 29, 100, + 232, 75, 110, 180, 226, 11, 143, 127, 79, 246, 48, 148, 229, 211, 204, 72, + 18, 89, 22, 251, 202, 8, 10, 2, 130, 230, 219, 71, 66, 142, 149, 47, + 12, 117, 202, 224, 248, 35, 75, 242, 87, 125, 230, 66, 38, 160, 62, 248, + 213, 32, 166, 83, 220, 230, 0, 1, 147, 51, 128, 110, 20, 16, 43, 142, + 90, 0, 2, 104, 111, 232, 38, 29, 181, 243, 130, 121, 105, 177, 168, 113, + 126, 191, 59, 205, 27, 180, 49, 128, 160, 225, 23, 173, 193, 155, 123, 12, + 173, 72, 139, 63, 23, 232, 138, 235, 39, 179, 158, 95, 103, 192, 13, 242, + 11, 127, 239, 91, 13, 119, 19, 185, 105, 87, 195, 168, 145, 15, 53, 146, + 35, 227, 101, 234, 198, 247, 19, 29, 134, 126, 211, 133, 78, 186, 127, 129, + 181, 115, 133, 62, 166, 133, 128, 225, 101, 98, 146, 175, 110, 113, 171, 117, + 4, 130, 190, 186, 216, 17, 201, 29, 62, 77, 74, 189, 50, 155, 188, 93, + 237, 26, 100, 225, 91, 120, 229, 163, 16, 210, 167, 138, 241, 147, 36, 56, + 12, 100, 33, 55, 232, 200, 118, 3, 222, 31, 72, 167, 91, 45, 133, 62, + 184, 64, 120, 116, 249, 12, 15, 243, 98, 145, 234, 253, 71, 194, 61, 4, + 102, 112, 35, 27, 75, 13, 1, 4, 128, 238, 170, 187, 80, 147, 216, 165, + 147, 248, 250, 241, 69, 106, 233, 227, 22, 153, 120, 138, 113, 83, 104, 154, + 50, 99, 153, 188, 69, 252, 171, 177, 49, 74, 134, 219, 247, 255, 191, 202, + 165, 239, 179, 147, 91, 215, 195, 157, 68, 21, 180, 112, 187, 51, 66, 80, + 205, 100, 35, 78, 59, 92, 175, 87, 224, 170, 237, 223, 224, 83, 182, 199, + 47, 95, 111, 42, 197, 22, 21, 143, 123, 173, 69, 247, 31, 205, 69, 136, + 137, 136, 241, 233, 67, 7, 225, 112, 102, 92, 180, 211, 254, 29, 129, 29, + 21, 188, 44, 95, 57, 122, 17, 196, 213, 33, 56, 23, 88, 236, 185, 35, + 17, 156, 165, 93, 108, 157, 198, 5, 124, 225, 150, 156, 146, 116, 88, 116, + 181, 207, 90, 85, 145, 228, 231, 91, 116, 79, 6, 119, 6, 207, 190, 102, + 72, 242, 2, 253, 79, 92, 88, 189, 28, 57, 28, 101, 199, 134, 124, 215, + 59, 37, 222, 54, 194, 151, 252, 185, 74, 101, 193, 43, 186, 184, 255, 158, + 129, 183, 83, 176, 249, 134, 58, 15, 49, 213, 127, 162, 179, 56, 53, 4, + 114, 112, 29, 84, 246, 109, 46, 153, 97, 30, 208, 98, 234, 155, 104, 158, + 93, 9, 53, 175, 49, 54, 160, 238, 150, 117, 145, 202, 210, 37, 15, 3, + 100, 20, 116, 153, 90, 23, 2, 146, 58, 182, 199, 197, 122, 89, 30, 152, + 241, 105, 97, 115, 131, 111, 4, 235, 217, 213, 144, 218, 217, 201, 141, 113, + 21, 237, 254, 184, 181, 135, 177, 86, 215, 248, 169, 55, 231, 229, 60, 133, + 12, 194, 206, 112, 206, 175, 216, 131, 181, 41, 154, 235, 76, 152, 58, 118, + 111, 32, 220, 219, 253, 198, 18, 227, 71, 129, 197, 227, 96, 155, 66, 0, + 51, 132, 150, 208, 177, 188, 149, 100, 236, 23, 49, 45, 236, 131, 225, 206, + 77, 77, 94, 12, 244, 159, 85, 247, 189, 109, 141, 217, 80, 115, 44, 171, + 138, 68, 128, 147, 244, 213, 43, 187, 135, 126, 156, 158, 199, 61, 180, 112, + 130, 230, 146, 100, 106, 56, 70, 71, 234, 3, 202, 1, 45, 20, 136, 149, + 112, 178, 25, 110, 160, 221, 57, 191, 78, 9, 250, 233, 4, 144, 28, 219, + 200, 203, 227, 218, 229, 108, 59, 221, 141, 0, 122, 121, 65, 156, 204, 19, + 152, 215, 64, 164, 15, 77, 26, 113, 82, 229, 23, 103, 204, 151, 118, 104, + 171, 115, 72, 191, 5, 159, 133, 83, 221, 228, 120, 127, 46, 233, 14, 27, + 216, 31, 63, 179, 224, 226, 121, 29, 62, 47, 199, 67, 60, 240, 85, 175, + 242, 113, 168, 160, 93, 147, 205, 103, 67, 110, 237, 143, 148, 65, 209, 31, + 100, 252, 166, 254, 170, 52, 203, 222, 75, 219, 77, 217, 202, 18, 117, 253, + 92, 29, 205, 115, 53, 255, 251, 150, 164, 72, 146, 6, 101, 161, 127, 50, + 73, 152, 194, 180, 11, 121, 11, 229, 147, 151, 143, 226, 196, 238, 131, 141, + 173, 153, 189, 114, 16, 82, 1, 70, 239, 22, 85, 108, 113, 21, 231, 43, + 6, 228, 54, 94, 200, 186, 190, 143, 117, 156, 22, 30, 9, 64, 25, 8, + 116, 27, 240, 24, 150, 146, 224, 73, 97, 95, 183, 151, 185, 178, 16, 82, + 243, 208, 160, 186, 246, 234, 223, 35, 6, 166, 7, 105, 224, 246, 14, 208, + 1, 70, 244, 221, 238, 235, 86, 81, 136, 40, 99, 104, 89, 22, 194, 40, + 36, 45, 126, 138, 174, 22, 206, 228, 146, 114, 162, 4, 211, 213, 163, 224, + 91, 3, 85, 140, 140, 202, 204, 23, 194, 108, 166, 123, 1, 36, 191, 161, + 38, 228, 65, 249, 235, 26, 156, 83, 68, 199, 239, 109, 1, 203, 198, 25, + 22, 128, 165, 15, 125, 139, 190, 100, 184, 159, 16, 194, 244, 228, 18, 215, + 103, 169, 32, 208, 12, 104, 94, 71, 209, 193, 160, 161, 73, 38, 35, 49, + 202, 29, 193, 120, 100, 98, 219, 44, 27, 224, 222, 226, 105, 153, 17, 252, + 120, 143, 190, 173, 176, 89, 205, 149, 11, 99, 31, 107, 102, 187, 100, 107, + 200, 1, 130, 89, 75, 71, 196, 150, 89, 231, 28, 213, 173, 229, 173, 104, + 156, 123, 227, 163, 65, 230, 167, 67, 242, 143, 224, 224, 161, 249, 205, 140, + 149, 156, 2, 138, 177, 193, 136, 225, 177, 34, 246, 27, 179, 108, 116, 169, + 0, 183, 169, 12, 239, 230, 127, 169, 170, 144, 151, 36, 111, 52, 132, 2, + 15, 237, 209, 133, 254, 241, 184, 232, 116, 11, 221, 210, 64, 96, 18, 30, + 245, 95, 142, 84, 218, 92, 151, 20, 155, 101, 201, 153, 82, 163, 43, 168, + 152, 90, 224, 18, 112, 161, 123, 115, 129, 136, 198, 50, 186, 239, 28, 80, + 91, 20, 73, 6, 150, 187, 56, 54, 200, 67, 26, 62, 0, 229, 42, 210, + 107, 245, 83, 172, 233, 195, 140, 31, 24, 205, 202, 128, 145, 242, 73, 113, + 92, 176, 3, 146, 170, 21, 106, 67, 53, 254, 192, 212, 194, 6, 52, 81, + 163, 236, 63, 95, 164, 91, 60, 20, 9, 201, 74, 143, 55, 110, 76, 61, + 115, 177, 84, 105, 191, 199, 248, 51, 89, 35, 91, 44, 199, 13, 254, 130, + 142, 136, 64, 111, 128, 229, 171, 208, 183, 242, 195, 251, 72, 168, 31, 76, + 89, 102, 122, 181, 57, 110, 17, 196, 31, 136, 185, 196, 118, 100, 188, 100, + 21, 239, 206, 77, 97, 238, 78, 215, 224, 113, 210, 122, 141, 190, 103, 135, + 12, 41, 206, 157, 154, 10, 167, 133, 183, 60, 230, 235, 109, 33, 95, 121, + 34, 206, 1, 149, 114, 4, 252, 42, 17, 93, 191, 144, 133, 226, 101, 215, + 124, 88, 163, 27, 29, 189, 35, 51, 182, 112, 242, 94, 56, 196, 99, 242, + 77, 95, 123, 219, 81, 71, 229, 138, 101, 8, 77, 79, 2, 166, 195, 239, + 148, 221, 188, 20, 170, 26, 215, 139, 42, 171, 153, 219, 107, 191, 90, 185, + 241, 37, 84, 41, 232, 27, 123, 36, 86, 113, 255, 25, 245, 187, 21, 110, + 13, 17, 43, 99, 91, 182, 243, 239, 194, 150, 187, 111, 30, 83, 28, 111, + 249, 159, 212, 187, 184, 177, 12, 234, 107, 211, 32, 118, 132, 10, 145, 19, + 150, 206, 230, 158, 80, 101, 41, 67, 38, 79, 57, 164, 80, 147, 64, 207, + 231, 229, 162, 5, 185, 40, 164, 17, 84, 156, 1, 52, 181, 67, 63, 182, + 25, 68, 55, 167, 230, 125, 225, 234, 125, 79, 102, 35, 54, 2, 12, 145, + 67, 6, 252, 218, 231, 14, 58, 221, 248, 171, 23, 93, 14, 51, 76, 155, + 97, 239, 11, 95, 245, 154, 209, 127, 208, 19, 209, 158, 67, 164, 1, 123, + 230, 90, 236, 148, 77, 210, 240, 27, 154, 16, 146, 19, 107, 106, 141, 94, + 144, 28, 24, 130, 111, 164, 46, 108, 89, 171, 52, 192, 121, 188, 166, 207, + 164, 98, 57, 189, 54, 190, 18, 4, 120, 181, 18, 216, 162, 19, 111, 254, + 71, 171, 194, 79, 73, 122, 9, 115, 63, 61, 88, 117, 234, 203, 250, 167, + 102, 98, 101, 177, 5, 13, 228, 205, 115, 107, 219, 215, 33, 150, 13, 242, + 180, 71, 27, 0, 250, 228, 50, 129, 215, 93, 174, 169, 167, 125, 14, 89, + 130, 195, 127, 158, 250, 249, 142, 213, 5, 1, 250, 31, 122, 171, 62, 142, + 38, 84, 165, 95, 237, 144, 145, 189, 193, 248, 121, 112, 22, 11, 26, 192, + 90, 76, 117, 89, 160, 228, 152, 24, 129, 235, 37, 24, 66, 68, 161, 126, + 147, 44, 172, 137, 134, 203, 162, 152, 255, 161, 135, 6, 31, 72, 69, 9, + 228, 3, 80, 28, 50, 240, 176, 66, 255, 231, 21, 233, 149, 55, 211, 15, + 182, 116, 165, 211, 190, 28, 69, 40, 3, 164, 172, 212, 150, 181, 213, 32, + 174, 216, 8, 243, 29, 152, 124, 7, 111, 140, 53, 157, 158, 233, 175, 60, + 191, 179, 131, 248, 252, 50, 171, 165, 5, 51, 69, 215, 168, 222, 57, 221, + 164, 56, 193, 114, 18, 89, 219, 222, 198, 163, 200, 233, 28, 51, 190, 25, + 206, 243, 63, 51, 44, 10, 57, 71, 252, 230, 161, 141, 79, 31, 30, 150, + 101, 168, 23, 70, 216, 216, 160, 241, 192, 106, 92, 194, 141, 81, 100, 222, + 165, 180, 27, 70, 201, 219, 31, 177, 189, 114, 30, 74, 6, 184, 114, 208, + 189, 246, 83, 107, 229, 153, 69, 66, 201, 253, 183, 5, 134, 156, 200, 132, + 187, 73, 175, 213, 178, 14, 66, 101, 13, 224, 49, 205, 244, 124, 231, 18, + 71, 94, 246, 29, 78, 201, 138, 60, 97, 54, 156, 123, 144, 143, 6, 191, + 113, 140, 251, 203, 125, 196, 135, 169, 197, 34, 215, 77, 138, 218, 63, 56, + 145, 74, 225, 15, 227, 112, 113, 160, 165, 122, 85, 179, 97, 146, 5, 221, + 133, 236, 170, 2, 236, 128, 19, 252, 238, 120, 0, 192, 55, 5, 138, 161, + 222, 148, 189, 130, 53, 250, 36, 153, 248, 210, 197, 167, 236, 128, 191, 37, + 251, 151, 163, 190, 155, 38, 27, 164, 166, 238, 185, 11, 214, 212, 122, 206, + 212, 255, 103, 255, 69, 146, 54, 182, 52, 54, 169, 121, 244, 205, 244, 168, + 96, 163, 220, 75, 194, 10, 133, 204, 105, 10, 228, 139, 62, 39, 254, 131, + 5, 243, 54, 14, 158, 107, 118, 143, 81, 55, 251, 151, 226, 29, 54, 218, + 99, 187, 76, 178, 61, 206, 20, 170, 229, 190, 77, 215, 47, 104, 244, 87, + 101, 82, 50, 41, 255, 56, 6, 226, 22, 153, 19, 72, 227, 63, 224, 79, + 3, 130, 220, 135, 116, 39, 25, 98, 107, 50, 214, 183, 120, 215, 26, 160, + 247, 26, 190, 119, 146, 181, 147, 36, 15, 75, 109, 71, 72, 44, 14, 9, + 61, 201, 200, 222, 53, 246, 57, 69, 63, 108, 133, 140, 150, 33, 233, 46, + 84, 102, 150, 204, 129, 195, 97, 4, 69, 176, 166, 182, 10, 237, 141, 33, + 70, 200, 98, 101, 157, 9, 70, 227, 108, 195, 241, 72, 105, 86, 67, 5, + 242, 199, 149, 33, 43, 105, 206, 122, 20, 13, 28, 158, 131, 47, 202, 70, + 9, 92, 32, 10, 251, 103, 49, 185, 35, 242, 168, 151, 234, 237, 212, 91, + 81, 113, 133, 247, 204, 23, 4, 9, 226, 14, 29, 117, 236, 101, 250, 46, + 161, 149, 131, 98, 141, 228, 72, 18, 164, 252, 56, 7, 160, 217, 183, 125, + 121, 154, 169, 152, 211, 114, 24, 190, 141, 135, 41, 173, 250, 50, 54, 197, + 65, 67, 117, 246, 235, 130, 142, 138, 62, 216, 51, 193, 247, 30, 164, 235, + 209, 157, 138, 4, 147, 6, 253, 187, 34, 124, 1, 143, 60, 95, 168, 72, + 167, 72, 72, 13, 142, 35, 185, 107, 29, 51, 189, 48, 141, 194, 33, 77, + 118, 17, 80, 88, 204, 147, 148, 143, 103, 246, 97, 180, 153, 160, 112, 81, + 196, 2, 222, 148, 126, 240, 27, 61, 128, 155, 184, 106, 89, 36, 136, 230, + 128, 84, 217, 130, 139, 104, 115, 225, 73, 77, 7, 49, 183, 4, 250, 124, + 196, 34, 183, 209, 17, 136, 92, 16, 94, 51, 78, 174, 185, 117, 243, 69, + 11, 214, 132, 72, 86, 212, 4, 193, 253, 125, 45, 148, 97, 87, 6, 101, + 195, 169, 86, 115, 218, 254, 40, 59, 255, 137, 135, 183, 253, 117, 170, 29, + 191, 138, 247, 117, 125, 234, 30, 40, 92, 8, 180, 240, 136, 142, 111, 239, + 66, 225, 196, 151, 93, 130, 126, 255, 195, 34, 252, 17, 101, 179, 120, 76, + 4, 227, 13, 12, 66, 205, 235, 177, 29, 187, 25, 114, 68, 119, 114, 158, + 213, 149, 210, 5, 104, 71, 181, 126, 211, 32, 99, 60, 51, 75, 85, 138, + 138, 68, 115, 81, 37, 17, 101, 36, 117, 236, 182, 77, 98, 113, 198, 195, + 73, 79, 215, 116, 248, 45, 244, 60, 205, 35, 95, 228, 38, 180, 250, 246, + 63, 211, 44, 197, 162, 24, 195, 61, 136, 142, 91, 141, 62, 34, 139, 60, + 142, 238, 67, 148, 54, 132, 41, 115, 241, 219, 192, 121, 9, 45, 75, 183, + 223, 213, 165, 161, 219, 181, 161, 27, 36, 158, 163, 12, 12, 141, 83, 105, + 157, 118, 168, 244, 204, 32, 52, 131, 88, 246, 230, 121, 21, 58, 91, 217, + 138, 27, 251, 174, 150, 51, 240, 201, 30, 66, 19, 148, 185, 122, 53, 15, + 176, 144, 148, 3, 238, 59, 211, 155, 77, 83, 81, 245, 186, 169, 217, 201, + 103, 109, 137, 119, 146, 100, 18, 200, 185, 212, 202, 17, 88, 146, 234, 49, + 190, 19, 139, 43, 1, 48, 21, 64, 235, 89, 191, 74, 89, 85, 16, 64, + 203, 99, 152, 255, 61, 159, 36, 5, 199, 49, 94, 229, 163, 192, 41, 165, + 20, 203, 176, 149, 18, 152, 61, 216, 188, 203, 180, 103, 202, 176, 177, 210, + 255, 26, 254, 70, 43, 214, 95, 208, 73, 148, 124, 19, 215, 68, 123, 10, + 179, 88, 167, 224, 23, 246, 150, 201, 51, 157, 139, 187, 103, 187, 198, 189, + 204, 126, 74, 124, 23, 150, 108, 116, 196, 130, 92, 0, 211, 151, 19, 58, + 249, 50, 186, 54, 102, 164, 122, 228, 71, 163, 163, 117, 78, 234, 197, 70, + 96, 79, 4, 88, 242, 219, 120, 28, 178, 165, 136, 178, 129, 125, 79, 140, + 65, 62, 78, 237, 104, 11, 45, 191, 163, 145, 174, 23, 34, 240, 43, 137, + 102, 189, 140, 137, 4, 222, 55, 6, 84, 194, 51, 164, 107, 234, 39, 216, + 15, 12, 44, 86, 170, 121, 46, 4, 220, 200, 42, 53, 11, 228, 110, 187, + 116, 182, 242, 42, 93, 109, 47, 109, 180, 155, 31, 99, 60, 107, 114, 82, + 196, 146, 45, 224, 90, 205, 34, 200, 42, 173, 113, 37, 26, 154, 74, 18, + 165, 45, 22, 141, 1, 244, 64, 159, 164, 162, 100, 6, 67, 145, 199, 205, + 254, 149, 56, 138, 15, 172, 205, 203, 191, 253, 126, 238, 167, 210, 103, 33, + 143, 85, 161, 150, 99, 12, 207, 238, 110, 157, 190, 52, 249, 121, 139, 188, + 0, 74, 92, 106, 101, 254, 190, 251, 213, 167, 78, 36, 224, 24, 6, 195, + 128, 24, 21, 35, 66, 223, 204, 84, 177, 109, 226, 215, 79, 19, 236, 73, + 74, 244, 146, 57, 228, 254, 223, 158, 42, 83, 29, 181, 14, 147, 60, 4, + 147, 107, 95, 220, 180, 130, 140, 28, 118, 179, 39, 179, 250, 184, 27, 209, + 199, 151, 154, 121, 105, 81, 215, 143, 46, 91, 217, 94, 230, 250, 165, 21, + 240, 234, 93, 0, 176, 20, 127, 181, 36, 127, 49, 36, 79, 233, 229, 57, + 241, 56, 119, 151, 222, 239, 203, 217, 74, 164, 88, 47, 25, 43, 58, 136, + 61, 233, 70, 133, 181, 122, 250, 169, 249, 38, 36, 40, 182, 201, 40, 64, + 218, 145, 63, 209, 126, 248, 65, 23, 142, 147, 3, 241, 200, 87, 132, 93, + 31, 22, 90, 86, 244, 47, 235, 53, 187, 96, 165, 221, 185, 118, 134, 129, + 94, 64, 188, 132, 216, 198, 131, 74, 193, 32, 41, 194, 69, 201, 64, 31, + 6, 235, 95, 181, 207, 187, 60, 250, 24, 233, 127, 4, 5, 190, 242, 168, + 239, 185, 172, 78, 136, 121, 180, 191, 84, 54, 252, 83, 202, 111, 32, 100, + 213, 7, 178, 225, 71, 68, 244, 36, 141, 242, 199, 185, 71, 55, 244, 166, + 113, 41, 66, 177, 55, 251, 179, 251, 194, 2, 54, 20, 100, 241, 82, 213, + 236, 45, 196, 119, 134, 167, 163, 134, 61, 218, 207, 200, 118, 143, 249, 165, + 105, 78, 208, 213, 206, 72, 76, 123, 47, 31, 9, 234, 18, 125, 95, 170, + 199, 123, 139, 158, 244, 171, 6, 202, 240, 214, 94, 46, 60, 109, 185, 175, + 204, 176, 229, 110, 139, 249, 234, 3, 202, 231, 25, 195, 150, 136, 186, 246, + 72, 242, 133, 249, 229, 58, 112, 28, 228, 121, 85, 115, 90, 95, 32, 141, + 135, 217, 12, 187, 50, 229, 66, 103, 204, 0, 93, 86, 245, 59, 173, 28, + 71, 131, 135, 118, 125, 113, 12, 13, 202, 242, 205, 255, 152, 243, 160, 243, + 148, 10, 28, 106, 56, 17, 93, 234, 204, 102, 53, 22, 48, 188, 15, 255, + 14, 3, 117, 190, 211, 116, 55, 77, 205, 171, 228, 120, 244, 1, 169, 51, + 241, 150, 206, 99, 20, 68, 119, 137, 180, 44, 113, 85, 242, 143, 148, 97, + 149, 75, 20, 228, 89, 226, 122, 102, 13, 195, 58, 111, 178, 82, 226, 144, + 82, 237, 27, 94, 244, 29, 102, 32, 162, 80, 228, 66, 203, 107, 211, 171, + 4, 56, 62, 184, 63, 137, 5, 179, 231, 185, 172, 102, 190, 42, 80, 164, + 123, 68, 20, 36, 135, 97, 102, 156, 133, 165, 202, 240, 84, 168, 30, 95, + 57, 3, 182, 224, 10, 84, 60, 88, 191, 0, 126, 190, 240, 202, 141, 89, + 238, 212, 101, 213, 129, 15, 245, 94, 24, 49, 72, 59, 237, 121, 241, 199, + 28, 106, 113, 237, 82, 144, 150, 112, 79, 90, 255, 166, 230, 71, 132, 24, + 6, 82, 143, 150, 194, 236, 253, 46, 158, 143, 5, 31, 243, 156, 4, 19, + 89, 81, 94, 94, 39, 9, 199, 6, 44, 35, 4, 143, 18, 62, 27, 165, + 177, 162, 53, 121, 146, 74, 181, 252, 27, 207, 17, 102, 196, 172, 75, 4, + 17, 215, 20, 96, 9, 42, 199, 99, 206, 94, 78, 121, 37, 11, 152, 125, + 249, 107, 153, 180, 85, 155, 220, 68, 223, 87, 204, 175, 117, 147, 217, 71, + 6, 190, 132, 99, 227, 5, 180, 168, 249, 126, 202, 102, 42, 26, 175, 198, + 185, 211, 206, 154, 60, 24, 183, 24, 203, 46, 21, 176, 194, 116, 116, 210, + 162, 214, 215, 79, 87, 159, 16, 55, 12, 248, 51, 17, 79, 183, 145, 23, + 209, 58, 225, 84, 21, 237, 102, 250, 93, 222, 87, 87, 203, 4, 138, 196, + 6, 28, 143, 45, 68, 77, 211, 180, 47, 198, 5, 170, 166, 221, 107, 202, + 67, 220, 178, 156, 39, 2, 87, 147, 234, 85, 199, 97, 10, 151, 240, 121, + 229, 132, 230, 249, 244, 57, 77, 29, 123, 149, 121, 81, 245, 37, 106, 157, + 39, 185, 31, 175, 102, 187, 37, 149, 27, 215, 151, 155, 94, 160, 180, 59, + 95, 200, 149, 42, 178, 85, 171, 41, 31, 20, 16, 199, 14, 202, 230, 42, + 59, 83, 239, 155, 65, 63, 237, 89, 133, 62, 23, 112, 236, 226, 34, 250, + 134, 14, 234, 2, 212, 41, 135, 189, 114, 60, 147, 49, 19, 193, 169, 157, + 41, 62, 36, 42, 2, 172, 237, 250, 86, 252, 199, 80, 194, 195, 182, 136, + 209, 90, 80, 9, 121, 164, 168, 99, 235, 131, 129, 59, 26, 41, 124, 194, + 110, 143, 183, 126, 91, 50, 168, 211, 43, 177, 95, 196, 94, 206, 214, 173, + 89, 152, 173, 39, 53, 190, 186, 193, 75, 23, 181, 65, 153, 57, 142, 215, + 155, 147, 241, 110, 230, 102, 176, 152, 227, 83, 87, 110, 243, 143, 254, 127, + 254, 117, 117, 173, 106, 80, 127, 231, 39, 220, 178, 44, 95, 30, 60, 222, + 212, 72, 169, 84, 194, 40, 164, 156, 145, 182, 127, 51, 64, 108, 144, 124, + 136, 238, 4, 113, 14, 68, 106, 158, 20, 231, 109, 99, 70, 214, 68, 29, + 240, 154, 95, 206, 188, 136, 180, 41, 220, 228, 198, 82, 51, 118, 65, 20, + 198, 187, 22, 8, 134, 252, 86, 227, 110, 105, 198, 242, 48, 8, 192, 165, + 80, 210, 1, 175, 188, 99, 252, 178, 7, 70, 27, 249, 175, 145, 131, 228, + 86, 229, 81, 93, 203, 194, 226, 110, 250, 134, 235, 195, 170, 107, 131, 185, + 81, 99, 168, 124, 215, 108, 40, 198, 193, 117, 88, 136, 134, 114, 145, 239, + 9, 0, 184, 106, 111, 63, 6, 92, 30, 3, 116, 7, 232, 182, 184, 60, + 32, 161, 183, 167, 163, 185, 114, 43, 77, 134, 29, 164, 135, 3, 155, 255, + 83, 254, 203, 1, 243, 167, 236, 162, 77, 140, 250, 224, 25, 246, 81, 147, + 207, 0, 127, 115, 127, 151, 191, 179, 128, 77, 142, 203, 171, 153, 47, 244, + 165, 235, 20, 64, 36, 99, 201, 190, 83, 244, 125, 112, 49, 26, 95, 125, + 254, 140, 85, 142, 112, 170, 225, 4, 126, 243, 224, 180, 137, 152, 102, 9, + 92, 67, 247, 20, 189, 58, 88, 74, 183, 201, 43, 1, 2, 123, 228, 211, + 79, 91, 20, 64, 111, 238, 60, 76, 207, 91, 90, 130, 169, 238, 254, 208, + 125, 140, 7, 94, 63, 18, 46, 124, 16, 253, 228, 238, 179, 99, 129, 40, + 89, 12, 40, 42, 94, 237, 111, 112, 22, 162, 64, 25, 89, 102, 56, 25, + 245, 128, 221, 86, 146, 138, 242, 67, 166, 114, 204, 38, 89, 77, 127, 64, + 36, 183, 161, 254, 185, 76, 91, 10, 28, 146, 154, 254, 118, 200, 206, 95, + 6, 182, 35, 178, 179, 114, 87, 60, 208, 88, 180, 161, 171, 39, 156, 131, + 2, 83, 124, 11, 223, 57, 190, 18, 79, 245, 198, 11, 55, 131, 197, 28, + 74, 32, 223, 144, 231, 227, 25, 237, 243, 145, 64, 183, 62, 163, 33, 93, + 155, 82, 228, 206, 69, 77, 101, 8, 240, 3, 135, 0, 181, 153, 174, 82, + 29, 129, 40, 83, 235, 83, 98, 105, 235, 210, 121, 239, 78, 240, 217, 144, + 230, 225, 3, 157, 14, 118, 64, 228, 29, 110, 230, 247, 153, 117, 3, 81, + 24, 23, 169, 2, 247, 238, 144, 137, 241, 140, 192, 185, 165, 13, 122, 48, + 180, 254, 54, 128, 134, 247, 87, 42, 219, 166, 7, 248, 91, 39, 226, 245, + 44, 152, 30, 71, 125, 129, 102, 72, 16, 66, 119, 15, 189, 250, 70, 112, + 168, 7, 5, 181, 15, 114, 73, 112, 16, 184, 65, 192, 54, 51, 31, 202, + 38, 11, 170, 149, 37, 107, 44, 241, 30, 35, 23, 176, 99, 82, 230, 60, + 206, 39, 249, 227, 114, 152, 133, 233, 60, 188, 79, 52, 241, 191, 208, 160, + 213, 159, 219, 188, 222, 47, 235, 187, 9, 186, 112, 78, 101, 229, 115, 152, + 216, 196, 88, 228, 189, 226, 214, 40, 163, 155, 193, 238, 224, 72, 64, 199, + 4, 182, 248, 143, 219, 170, 227, 55, 215, 135, 92, 117, 56, 225, 220, 129, + 74, 226, 55, 132, 73, 213, 81, 93, 107, 49, 29, 155, 62, 141, 48, 190, + 242, 221, 95, 61, 179, 165, 213, 49, 125, 245, 106, 35, 24, 57, 103, 140, + 79, 172, 38, 29, 170, 145, 151, 204, 114, 161, 117, 2, 199, 145, 210, 184, + 71, 80, 251, 182, 67, 220, 3, 2, 210, 28, 17, 104, 68, 150, 255, 174, + 34, 206, 245, 97, 173, 8, 92, 160, 144, 149, 54, 57, 114, 145, 215, 115, + 186, 145, 165, 186, 207, 107, 14, 255, 88, 145, 225, 110, 190, 78, 93, 147, + 225, 247, 122, 52, 135, 147, 89, 3, 10, 119, 43, 154, 29, 186, 68, 50, + 125, 152, 205, 242, 113, 106, 80, 68, 21, 45, 147, 212, 5, 1, 27, 39, + 51, 221, 25, 38, 102, 67, 194, 250, 121, 51, 66, 76, 155, 205, 199, 54, + 177, 202, 0, 249, 225, 231, 179, 69, 52, 22, 87, 77, 193, 35, 88, 3, + 238, 62, 12, 159, 221, 203, 230, 122, 92, 71, 26, 218, 41, 218, 75, 21, + 201, 166, 224, 173, 110, 185, 97, 161, 227, 9, 43, 108, 162, 62, 228, 201, + 32, 178, 191, 115, 35, 118, 59, 165, 223, 135, 132, 230, 110, 213, 96, 68, + 190, 237, 213, 146, 85, 179, 242, 155, 122, 217, 7, 105, 70, 123, 10, 5, + 122, 153, 202, 218, 195, 207, 73, 175, 161, 31, 200, 47, 237, 64, 34, 227, + 34, 66, 58, 29, 28, 166, 242, 128, 33, 79, 32, 125, 60, 207, 222, 195, + 180, 137, 78, 177, 132, 249, 147, 38, 64, 247, 181, 81, 96, 155, 167, 113, + 95, 197, 30, 83, 18, 128, 93, 131, 242, 197, 50, 146, 106, 143, 56, 216, + 80, 80, 159, 164, 154, 220, 248, 193, 58, 253, 63, 219, 91, 140, 170, 71, + 152, 8, 69, 37, 138, 179, 223, 54, 98, 229, 181, 107, 50, 174, 6, 20, + 69, 101, 50, 57, 102, 61, 123, 218, 226, 77, 25, 129, 188, 103, 22, 81, + 66, 232, 19, 88, 103, 184, 87, 252, 109, 31, 242, 40, 37, 238, 237, 20, + 232, 170, 115, 36, 83, 127, 65, 208, 85, 56, 192, 120, 116, 153, 200, 116, + 108, 243, 110, 8, 9, 162, 206, 172, 25, 0, 103, 79, 239, 8, 184, 142, + 87, 86, 95, 139, 223, 180, 6, 205, 39, 76, 25, 62, 32, 244, 171, 152, + 146, 48, 224, 20, 23, 219, 250, 115, 159, 131, 14, 91, 5, 27, 26, 60, + 239, 5, 41, 159, 226, 103, 177, 43, 224, 51, 123, 129, 148, 18, 241, 66, + 192, 199, 151, 94, 207, 238, 120, 34, 234, 75, 193, 65, 66, 243, 125, 21, + 57, 113, 143, 44, 49, 153, 168, 129, 102, 21, 17, 101, 182, 217, 216, 17, + 7, 70, 99, 194, 34, 47, 49, 241, 25, 242, 163, 251, 28, 172, 167, 4, + 96, 213, 236, 60, 223, 52, 150, 216, 168, 157, 5, 56, 126, 50, 228, 130, + 166, 54, 196, 85, 86, 162, 154, 82, 84, 34, 228, 235, 157, 230, 47, 77, + 151, 127, 226, 82, 145, 205, 201, 40, 49, 178, 228, 77, 132, 208, 93, 4, + 2, 73, 46, 69, 188, 60, 130, 217, 1, 97, 177, 240, 18, 26, 141, 97, + 5, 170, 82, 56, 218, 83, 3, 29, 228, 13, 179, 232, 154, 50, 152, 40, + 58, 0, 202, 195, 36, 91, 104, 37, 10, 89, 0, 250, 146, 45, 248, 68, + 37, 180, 129, 46, 138, 43, 98, 40, 122, 174, 147, 85, 94, 255, 76, 129, + 245, 135, 198, 206, 144, 189, 190, 207, 253, 191, 104, 163, 141, 116, 1, 192, + 200, 193, 205, 196, 151, 231, 254, 190, 17, 172, 254, 196, 243, 72, 234, 236, + 92, 108, 153, 184, 39, 201, 109, 233, 38, 178, 163, 46, 150, 153, 170, 238, + 84, 196, 155, 171, 31, 3, 186, 55, 87, 100, 179, 61, 163, 119, 82, 75, + 107, 173, 8, 145, 135, 226, 243, 8, 38, 102, 123, 120, 169, 215, 177, 132, + 111, 26, 242, 205, 150, 143, 197, 152, 137, 193, 174, 171, 234, 183, 221, 189, + 40, 212, 191, 137, 47, 153, 85, 76, 59, 255, 16, 51, 186, 105, 224, 14, + 73, 41, 84, 42, 12, 186, 198, 133, 82, 8, 161, 173, 130, 25, 26, 22, + 152, 132, 221, 182, 68, 126, 160, 248, 183, 112, 129, 83, 181, 55, 17, 145, + 18, 220, 143, 17, 49, 18, 15, 191, 104, 40, 67, 139, 127, 106, 56, 65, + 4, 120, 100, 5, 88, 44, 82, 240, 138, 64, 42, 158, 24, 130, 133, 237, + 235, 112, 115, 164, 249, 247, 233, 173, 116, 245, 23, 37, 216, 180, 118, 183, + 58, 246, 254, 103, 93, 55, 36, 213, 76, 134, 122, 116, 164, 15, 11, 115, + 168, 185, 226, 79, 250, 236, 172, 24, 226, 48, 150, 67, 128, 63, 211, 235, + 219, 120, 216, 18, 31, 82, 136, 105, 151, 118, 193, 43, 33, 155, 55, 8, + 17, 3, 211, 110, 115, 27, 122, 3, 195, 97, 1, 227, 22, 124, 213, 59, + 89, 13, 253, 221, 207, 229, 25, 72, 200, 144, 209, 147, 185, 68, 132, 104, + 7, 34, 237, 45, 2, 17, 209, 87, 170, 227, 60, 230, 53, 186, 59, 39, + 254, 57, 191, 201, 59, 202, 119, 144, 163, 255, 78, 199, 9, 59, 129, 64, + 232, 31, 20, 110, 63, 172, 85, 239, 97, 216, 252, 158, 76, 64, 55, 133, + 43, 101, 22, 4, 27, 134, 210, 9, 120, 44, 255, 105, 142, 83, 6, 238, + 61, 226, 118, 111, 217, 234, 153, 48, 9, 193, 133, 172, 20, 121, 210, 40, + 243, 49, 13, 184, 152, 126, 248, 100, 37, 187, 216, 15, 250, 86, 178, 24, + 30, 174, 216, 151, 139, 27, 166, 190, 200, 228, 25, 152, 212, 70, 7, 45, + 141, 54, 143, 106, 206, 49, 170, 195, 61, 24, 81, 20, 116, 147, 95, 49, + 245, 179, 223, 237, 184, 110, 49, 158, 190, 211, 132, 30, 22, 195, 234, 167, + 143, 4, 26, 9, 215, 48, 100, 53, 221, 177, 172, 132, 184, 229, 165, 207, + 213, 192, 26, 58, 211, 227, 65, 148, 198, 5, 248, 169, 32, 121, 24, 164, + 193, 137, 218, 218, 105, 42, 136, 146, 91, 72, 238, 231, 24, 17, 108, 194, + 206, 5, 180, 101, 199, 161, 172, 130, 78, 110, 255, 62, 158, 111, 204, 223, + 33, 183, 43, 10, 93, 253, 249, 193, 149, 89, 21, 51, 198, 186, 91, 142, + 121, 157, 35, 254, 21, 55, 2, 7, 119, 32, 175, 107, 199, 86, 174, 37, + 144, 192, 13, 234, 244, 152, 150, 77, 69, 91, 174, 141, 211, 71, 85, 190, + 231, 124, 80, 80, 137, 195, 5, 196, 21, 239, 110, 92, 99, 158, 247, 229, + 178, 99, 156, 222, 135, 119, 197, 242, 98, 58, 0, 134, 97, 197, 30, 113, + 164, 183, 9, 1, 97, 166, 94, 117, 183, 103, 45, 147, 215, 137, 8, 64, + 9, 149, 66, 130, 166, 94, 72, 48, 181, 156, 233, 167, 116, 59, 10, 117, + 203, 53, 110, 133, 3, 97, 84, 60, 179, 90, 47, 45, 78, 41, 89, 191, + 234, 81, 129, 69, 179, 76, 221, 176, 171, 58, 158, 151, 251, 79, 189, 124, + 159, 40, 189, 229, 126, 168, 24, 141, 209, 215, 105, 170, 166, 181, 113, 36, + 4, 172, 90, 123, 232, 154, 150, 224, 87, 249, 134, 136, 14, 28, 23, 67, + 78, 187, 209, 55, 157, 95, 36, 136, 83, 103, 54, 236, 62, 81, 66, 44, + 85, 120, 219, 178, 62, 126, 203, 193, 229, 146, 25, 187, 254, 141, 147, 185, + 158, 103, 216, 216, 38, 34, 245, 43, 169, 200, 129, 130, 7, 239, 207, 155, + 250, 89, 209, 238, 20, 74, 133, 100, 67, 149, 41, 187, 72, 9, 135, 165, + 140, 14, 90, 51, 241, 216, 7, 176, 238, 254, 84, 53, 231, 87, 12, 51, + 222, 54, 70, 163, 101, 130, 63, 37, 120, 180, 219, 161, 69, 213, 233, 130, + 199, 124, 2, 36, 224, 140, 95, 201, 23, 72, 219, 222, 181, 237, 134, 11, + 103, 94, 246, 251, 215, 218, 228, 90, 36, 54, 237, 49, 204, 13, 194, 221, + 18, 186, 35, 144, 179, 2, 98, 90, 110, 165, 66, 38, 152, 206, 0, 121, + 90, 25, 94, 145, 133, 58, 143, 138, 175, 80, 233, 110, 78, 84, 0, 207, + 87, 78, 27, 243, 160, 231, 241, 83, 173, 163, 191, 205, 184, 216, 232, 36, + 194, 52, 5, 72, 249, 42, 103, 254, 213, 41, 159, 209, 56, 222, 40, 224, + 177, 195, 214, 11, 84, 221, 245, 137, 131, 23, 220, 251, 167, 17, 34, 214, + 41, 102, 226, 223, 79, 53, 119, 84, 17, 219, 19, 80, 90, 132, 19, 176, + 73, 145, 38, 28, 198, 176, 141, 92, 242, 69, 174, 63, 244, 44, 152, 102, + 120, 151, 167, 115, 67, 110, 119, 159, 56, 63, 29, 70, 253, 118, 119, 220, + 181, 71, 193, 167, 77, 178, 236, 187, 193, 236, 147, 231, 209, 56, 168, 202, + 7, 198, 208, 17, 20, 31, 42, 70, 237, 148, 162, 161, 128, 135, 88, 37, + 219, 56, 83, 248, 116, 20, 44, 17, 231, 156, 187, 251, 237, 165, 123, 165, + 181, 166, 212, 99, 132, 26, 122, 240, 223, 130, 235, 248, 239, 11, 161, 32, + 109, 210, 97, 173, 12, 251, 94, 118, 7, 107, 206, 105, 158, 16, 4, 245, + 159, 67, 150, 226, 53, 42, 241, 249, 146, 107, 111, 75, 147, 136, 141, 97, + 49, 101, 233, 168, 197, 72, 95, 138, 162, 103, 154, 162, 192, 78, 41, 102, + 52, 207, 165, 48, 93, 41, 104, 136, 91, 169, 167, 51, 217, 197, 25, 238, + 3, 4, 35, 64, 146, 153, 32, 107, 66, 225, 249, 148, 225, 130, 197, 194, + 34, 100, 235, 200, 204, 39, 230, 37, 103, 219, 139, 8, 232, 63, 95, 154, + 76, 195, 226, 187, 206, 116, 21, 40, 98, 177, 244, 9, 114, 148, 22, 185, + 243, 93, 8, 84, 137, 114, 217, 240, 69, 185, 123, 1, 225, 160, 221, 183, + 81, 159, 31, 66, 221, 201, 197, 113, 137, 181, 249, 211, 211, 226, 62, 12, + 116, 111, 130, 197, 99, 85, 29, 191, 94, 14, 166, 137, 147, 14, 133, 58, + 230, 148, 144, 87, 48, 117, 252, 64, 114, 18, 185, 63, 164, 159, 26, 79, + 188, 242, 126, 223, 213, 245, 195, 144, 19, 68, 175, 73, 15, 90, 45, 245, + 111, 212, 15, 108, 108, 199, 180, 231, 92, 251, 69, 251, 100, 179, 160, 125, + 250, 42, 79, 118, 101, 195, 108, 15, 243, 124, 76, 248, 137, 80, 49, 16, + 233, 89, 247, 188, 102, 212, 82, 111, 184, 67, 70, 110, 79, 241, 15, 157, + 225, 66, 87, 81, 35, 200, 210, 21, 243, 196, 86, 48, 46, 152, 150, 236, + 76, 45, 178, 131, 90, 85, 147, 107, 25, 194, 182, 106, 191, 161, 71, 94, + 211, 172, 93, 128, 17, 188, 240, 127, 4, 18, 124, 199, 122, 163, 140, 228, + 91, 163, 59, 197, 191, 231, 162, 77, 248, 24, 168, 119, 182, 169, 140, 55, + 207, 105, 70, 81, 32, 79, 212, 1, 59, 11, 55, 145, 61, 90, 134, 202, + 49, 105, 117, 158, 91, 86, 139, 55, 90, 171, 167, 237, 141, 1, 184, 49, + 63, 7, 226, 53, 153, 200, 188, 224, 234, 104, 101, 118, 238, 93, 34, 252, + 120, 251, 177, 103, 213, 173, 184, 231, 225, 111, 186, 210, 40, 111, 65, 4, + 60, 124, 221, 67, 201, 210, 65, 90, 74, 36, 39, 88, 233, 64, 172, 179, + 18, 59, 182, 82, 152, 192, 154, 220, 209, 184, 218, 210, 172, 250, 155, 199, + 175, 246, 218, 45, 211, 204, 131, 204, 73, 107, 246, 52, 133, 102, 103, 135, + 5, 46, 175, 63, 204, 92, 108, 126, 126, 194, 208, 178, 166, 198, 191, 240, + 128, 5, 203, 189, 102, 148, 65, 29, 146, 2, 24, 21, 201, 147, 145, 248, + 85, 77, 63, 245, 176, 199, 198, 237, 34, 101, 159, 144, 166, 29, 102, 175, + 121, 78, 75, 196, 204, 80, 156, 236, 198, 232, 117, 112, 135, 61, 63, 63, + 82, 2, 65, 139, 70, 69, 78, 64, 48, 154, 15, 250, 79, 190, 251, 94, + 205, 252, 236, 241, 2, 171, 232, 118, 128, 71, 18, 55, 49, 13, 27, 36, + 149, 220, 149, 150, 55, 200, 192, 151, 47, 218, 134, 205, 93, 7, 206, 44, + 229, 208, 62, 208, 55, 55, 239, 63, 45, 154, 171, 70, 223, 144, 78, 251, + 5, 138, 224, 21, 184, 87, 55, 69, 224, 231, 37, 65, 87, 114, 78, 216, + 41, 49, 143, 233, 182, 214, 84, 20, 20, 156, 17, 12, 173, 172, 80, 151, + 37, 28, 191, 69, 146, 102, 65, 15, 152, 143, 198, 45, 204, 4, 140, 90, + 149, 45, 157, 190, 119, 196, 121, 199, 176, 122, 198, 141, 161, 31, 24, 149, + 96, 231, 70, 122, 160, 19, 100, 75, 112, 141, 18, 175, 109, 98, 19, 110, + 237, 1, 5, 171, 153, 19, 251, 61, 180, 249, 9, 187, 196, 248, 127, 13, + 21, 244, 224, 42, 97, 40, 236, 190, 18, 123, 133, 26, 235, 9, 150, 90, + 21, 189, 189, 101, 226, 190, 82, 18, 45, 3, 172, 187, 72, 74, 244, 211, + 76, 2, 70, 168, 41, 195, 165, 178, 139, 5, 155, 100, 199, 0, 227, 72, + 247, 186, 33, 169, 34, 104, 196, 3, 253, 202, 19, 140, 100, 122, 144, 125, + 201, 202, 194, 245, 180, 27, 10, 207, 180, 31, 25, 152, 243, 143, 51, 90, + 33, 74, 147, 127, 66, 47, 10, 65, 99, 71, 243, 241, 221, 219, 32, 213, + 98, 67, 119, 130, 254, 11, 149, 64, 73, 168, 73, 237, 110, 18, 243, 21, + 177, 53, 109, 2, 242, 89, 136, 34, 36, 135, 12, 12, 125, 251, 104, 137, + 128, 152, 41, 70, 163, 184, 237, 137, 249, 63, 56, 133, 39, 0, 243, 248, + 80, 184, 48, 238, 155, 193, 21, 137, 95, 144, 146, 209, 151, 197, 199, 122, + 60, 48, 250, 1, 79, 162, 58, 78, 225, 184, 199, 35, 186, 225, 19, 68, + 31, 199, 150, 85, 197, 76, 246, 150, 47, 63, 55, 196, 200, 10, 163, 170, + 246, 34, 196, 87, 0, 45, 18, 6, 168, 248, 130, 184, 5, 197, 97, 56, + 128, 254, 236, 32, 10, 182, 198, 139, 255, 43, 41, 159, 119, 253, 81, 248, + 251, 253, 184, 98, 229, 6, 8, 64, 48, 190, 105, 125, 168, 191, 43, 93, + 156, 39, 244, 220, 138, 197, 117, 27, 152, 145, 254, 233, 211, 33, 234, 5, + 72, 247, 49, 221, 35, 188, 210, 20, 231, 90, 255, 37, 30, 126, 209, 65, + 137, 123, 126, 191, 158, 227, 201, 129, 19, 164, 51, 232, 188, 185, 96, 67, + 24, 190, 56, 16, 229, 34, 219, 150, 137, 226, 59, 58, 3, 147, 232, 35, + 99, 207, 101, 173, 217, 18, 139, 1, 94, 123, 4, 232, 147, 243, 13, 193, + 193, 187, 232, 100, 187, 119, 105, 72, 86, 30, 165, 20, 192, 19, 157, 67, + 253, 204, 246, 133, 85, 252, 109, 169, 106, 203, 83, 72, 51, 217, 172, 7, + 212, 104, 170, 166, 21, 181, 11, 14, 145, 33, 175, 235, 169, 66, 203, 78, + 108, 209, 100, 131, 93, 192, 70, 157, 186, 224, 174, 173, 22, 167, 87, 244, + 227, 218, 96, 98, 186, 24, 205, 62, 66, 79, 198, 254, 160, 37, 127, 16, + 95, 171, 47, 34, 80, 43, 26, 111, 65, 207, 29, 139, 135, 69, 13, 110, + 133, 110, 65, 140, 61, 207, 117, 98, 106, 29, 166, 224, 78, 208, 252, 194, + 91, 4, 38, 0, 61, 133, 180, 168, 149, 211, 7, 80, 227, 135, 51, 11, + 249, 228, 26, 198, 244, 2, 47, 226, 93, 147, 222, 125, 200, 205, 166, 154, + 234, 80, 39, 70, 84, 98, 209, 1, 6, 219, 17, 11, 253, 126, 145, 231, + 131, 14, 163, 107, 200, 195, 167, 64, 6, 101, 209, 255, 116, 179, 69, 164, + 133, 23, 78, 98, 105, 182, 236, 34, 246, 58, 81, 183, 100, 30, 44, 187, + 164, 91, 239, 132, 51, 154, 9, 2, 215, 186, 191, 79, 237, 179, 141, 169, + 237, 206, 190, 201, 64, 223, 143, 60, 173, 108, 96, 216, 183, 70, 110, 5, + 59, 230, 206, 194, 40, 211, 109, 146, 1, 102, 194, 212, 90, 214, 43, 111, + 134, 122, 146, 9, 220, 198, 72, 196, 68, 19, 214, 220, 11, 173, 243, 15, + 254, 158, 193, 211, 191, 55, 163, 212, 18, 20, 42, 199, 191, 74, 238, 191, + 113, 173, 125, 203, 48, 1, 119, 32, 224, 8, 178, 179, 0, 67, 153, 62, + 227, 25, 254, 126, 23, 87, 67, 43, 45, 250, 42, 214, 118, 179, 111, 189, + 103, 133, 35, 196, 54, 23, 203, 218, 59, 177, 194, 55, 210, 153, 78, 207, + 145, 157, 229, 119, 218, 173, 20, 104, 251, 48, 204, 245, 166, 251, 123, 82, + 175, 239, 215, 158, 200, 1, 174, 40, 200, 32, 108, 184, 0, 137, 90, 81, + 159, 128, 165, 10, 233, 210, 52, 48, 74, 164, 246, 199, 240, 154, 12, 254, + 70, 37, 106, 44, 85, 123, 151, 119, 153, 170, 48, 144, 241, 114, 64, 115, + 120, 159, 13, 49, 211, 182, 99, 124, 25, 70, 73, 196, 179, 201, 219, 124, + 22, 137, 229, 160, 155, 10, 158, 234, 132, 203, 208, 76, 81, 98, 30, 142, + 154, 68, 158, 92, 107, 252, 4, 22, 218, 2, 167, 190, 152, 141, 251, 137, + 236, 87, 186, 235, 90, 0, 132, 68, 232, 66, 63, 0, 41, 235, 157, 45, + 68, 194, 45, 18, 249, 254, 60, 33, 10, 86, 183, 45, 5, 253, 253, 212, + 44, 94, 203, 41, 53, 146, 101, 148, 123, 198, 92, 14, 181, 87, 49, 229, + 177, 249, 216, 8, 12, 37, 108, 220, 236, 13, 72, 122, 48, 235, 219, 74, + 220, 187, 130, 66, 249, 41, 184, 140, 101, 1, 203, 110, 22, 62, 23, 118, + 199, 32, 191, 162, 140, 187, 157, 80, 144, 59, 112, 238, 32, 101, 238, 47, + 225, 69, 99, 178, 246, 49, 76, 81, 101, 187, 71, 59, 140, 229, 81, 253, + 42, 204, 158, 74, 184, 237, 197, 14, 91, 81, 34, 115, 123, 224, 167, 15, + 112, 84, 225, 104, 103, 208, 236, 183, 185, 142, 175, 147, 237, 188, 159, 125, + 142, 253, 121, 87, 239, 78, 57, 179, 13, 123, 74, 148, 197, 74, 227, 110, + 48, 248, 165, 248, 249, 43, 249, 0, 69, 7, 183, 68, 167, 181, 39, 54, + 144, 39, 212, 36, 40, 171, 48, 106, 76, 50, 201, 111, 254, 86, 240, 39, + 14, 59, 58, 110, 54, 155, 2, 6, 205, 190, 237, 126, 58, 204, 112, 159, + 145, 188, 208, 196, 197, 52, 54, 94, 84, 127, 46, 56, 93, 152, 190, 133, + 120, 166, 75, 52, 6, 112, 112, 71, 119, 143, 218, 19, 242, 174, 48, 246, + 29, 243, 137, 94, 127, 95, 76, 49, 20, 149, 159, 251, 59, 146, 102, 242, + 222, 157, 162, 124, 154, 25, 47, 246, 135, 38, 177, 165, 246, 224, 202, 4, + 177, 255, 203, 245, 58, 172, 164, 33, 155, 179, 56, 41, 202, 39, 145, 176, + 130, 171, 30, 77, 177, 64, 203, 70, 230, 242, 240, 118, 145, 30, 89, 184, + 11, 123, 157, 212, 156, 28, 5, 200, 96, 157, 102, 126, 212, 149, 137, 144, + 169, 39, 211, 159, 193, 254, 65, 201, 154, 165, 37, 129, 14, 242, 28, 37, + 17, 130, 202, 227, 241, 49, 191, 213, 179, 72, 243, 118, 52, 133, 149, 8, + 156, 231, 94, 215, 15, 21, 118, 194, 254, 107, 249, 40, 153, 69, 95, 141, + 97, 37, 224, 82, 146, 71, 35, 26, 88, 127, 137, 247, 242, 243, 135, 113, + 189, 155, 56, 98, 99, 90, 108, 186, 118, 178, 253, 50, 44, 30, 43, 223, + 171, 186, 44, 120, 215, 128, 45, 65, 178, 142, 159, 39, 70, 37, 168, 62, + 127, 219, 111, 40, 239, 134, 47, 114, 69, 45, 87, 15, 234, 100, 9, 90, + 220, 203, 241, 40, 150, 239, 164, 39, 164, 196, 117, 156, 132, 143, 87, 146, + 190, 130, 168, 244, 193, 101, 110, 158, 231, 57, 146, 235, 227, 8, 12, 208, + 209, 203, 35, 38, 242, 45, 43, 118, 252, 201, 244, 130, 42, 18, 133, 66, + 129, 209, 77, 208, 69, 236, 138, 254, 255, 245, 112, 236, 86, 171, 1, 111, + 107, 69, 213, 222, 232, 199, 49, 193, 174, 198, 100, 170, 183, 150, 10, 233, + 28, 210, 219, 123, 233, 126, 105, 75, 222, 231, 13, 137, 242, 177, 41, 137, + 60, 202, 92, 16, 131, 226, 193, 152, 79, 95, 235, 105, 227, 172, 7, 160, + 180, 146, 190, 243, 34, 19, 186, 215, 106, 95, 152, 49, 90, 68, 71, 90, + 222, 240, 72, 16, 153, 69, 114, 193, 215, 175, 165, 224, 198, 154, 70, 104, + 79, 97, 153, 54, 153, 179, 2, 207, 197, 243, 12, 159, 76, 168, 136, 217, + 116, 79, 104, 21, 215, 72, 199, 35, 153, 67, 50, 145, 11, 253, 62, 254, + 121, 1, 8, 147, 39, 20, 94, 155, 80, 41, 135, 135, 45, 85, 61, 140, + 26, 195, 80, 187, 252, 175, 253, 152, 170, 169, 118, 235, 158, 134, 82, 188, + 86, 52, 70, 32, 239, 212, 157, 115, 137, 28, 191, 156, 197, 136, 226, 171, + 17, 231, 181, 79, 246, 232, 178, 242, 233, 113, 210, 230, 35, 201, 213, 28, + 72, 27, 183, 26, 106, 240, 111, 111, 255, 122, 128, 234, 179, 201, 66, 165, + 245, 198, 201, 138, 20, 212, 139, 159, 200, 91, 150, 175, 209, 203, 255, 81, + 30, 27, 83, 216, 119, 36, 48, 112, 237, 229, 175, 204, 149, 192, 183, 184, + 165, 176, 231, 176, 223, 81, 214, 225, 145, 107, 248, 225, 213, 6, 99, 59, + 197, 183, 125, 208, 26, 19, 178, 146, 154, 242, 71, 189, 11, 246, 48, 8, + 7, 28, 105, 208, 20, 13, 236, 77, 244, 218, 101, 217, 125, 199, 153, 77, + 193, 214, 233, 91, 48, 201, 209, 6, 155, 87, 208, 221, 9, 73, 76, 191, + 23, 249, 237, 146, 189, 177, 55, 8, 68, 192, 111, 204, 19, 164, 189, 223, + 83, 220, 156, 79, 12, 82, 178, 149, 102, 94, 120, 229, 198, 77, 136, 244, + 84, 33, 90, 66, 193, 45, 252, 160, 151, 66, 240, 135, 232, 147, 235, 107, + 173, 30, 184, 103, 131, 168, 55, 195, 111, 16, 202, 227, 203, 16, 14, 226, + 104, 220, 126, 121, 163, 5, 26, 253, 35, 196, 13, 90, 196, 32, 157, 28, + 152, 70, 205, 236, 101, 142, 207, 126, 230, 67, 194, 143, 67, 77, 91, 97, + 71, 135, 244, 40, 104, 120, 39, 169, 91, 124, 162, 111, 121, 9, 118, 146, + 215, 112, 120, 157, 22, 198, 241, 196, 32, 176, 60, 244, 197, 37, 210, 215, + 125, 122, 143, 253, 175, 101, 92, 205, 43, 170, 70, 183, 173, 162, 130, 226, + 41, 122, 158, 130, 183, 223, 162, 212, 194, 38, 133, 252, 57, 245, 187, 168, + 165, 204, 119, 8, 249, 174, 10, 206, 251, 55, 212, 118, 212, 74, 226, 227, + 141, 138, 122, 204, 83, 14, 175, 248, 18, 159, 79, 79, 100, 56, 37, 229, + 209, 221, 238, 197, 164, 42, 159, 203, 67, 31, 8, 195, 72, 251, 142, 229, + 60, 24, 254, 97, 124, 219, 201, 255, 232, 60, 77, 19, 220, 239, 10, 158, + 62, 117, 245, 167, 63, 38, 216, 169, 209, 29, 245, 17, 4, 241, 218, 83, + 72, 48, 214, 228, 85, 103, 116, 248, 133, 200, 75, 81, 220, 207, 59, 226, + 102, 50, 238, 138, 44, 120, 162, 220, 105, 5, 120, 11, 153, 98, 144, 4, + 197, 217, 39, 235, 141, 148, 123, 51, 213, 255, 144, 17, 189, 144, 214, 246, + 45, 95, 229, 127, 107, 19, 164, 143, 48, 210, 29, 249, 66, 11, 171, 191, + 73, 99, 161, 114, 190, 80, 31, 215, 67, 16, 187, 246, 47, 110, 157, 33, + 208, 151, 122, 2, 228, 161, 51, 9, 215, 33, 246, 67, 44, 19, 41, 29, + 10, 42, 130, 244, 95, 45, 199, 156, 251, 151, 210, 121, 198, 52, 44, 87, + 214, 126, 214, 93, 242, 201, 31, 44, 250, 139, 78, 59, 95, 116, 45, 100, + 187, 97, 206, 143, 158, 54, 98, 113, 30, 101, 151, 56, 187, 116, 199, 157, + 108, 136, 90, 36, 85, 253, 171, 140, 253, 14, 229, 238, 65, 220, 56, 162, + 194, 138, 46, 251, 90, 92, 121, 202, 202, 98, 133, 78, 229, 87, 31, 158, + 12, 175, 122, 17, 65, 10, 163, 51, 163, 95, 143, 208, 9, 192, 58, 29, + 130, 4, 237, 194, 246, 82, 11, 20, 49, 26, 177, 34, 202, 180, 210, 111, + 234, 151, 37, 27, 225, 7, 205, 35, 242, 176, 98, 232, 60, 89, 99, 33, + 233, 106, 236, 96, 248, 71, 101, 133, 44, 190, 241, 76, 113, 146, 181, 106, + 191, 130, 100, 127, 206, 138, 118, 124, 159, 138, 215, 82, 22, 224, 17, 114, + 127, 109, 203, 60, 33, 67, 126, 145, 25, 199, 88, 97, 150, 40, 68, 185, + 144, 218, 230, 81, 203, 223, 45, 209, 250, 22, 234, 12, 153, 49, 19, 107, + 97, 79, 126, 100, 128, 16, 12, 83, 74, 94, 23, 159, 192, 193, 74, 153, + 246, 12, 157, 248, 106, 34, 35, 64, 99, 184, 137, 91, 26, 154, 127, 155, + 218, 36, 185, 64, 26, 41, 236, 232, 223, 159, 10, 29, 165, 12, 244, 214, + 231, 231, 212, 154, 169, 66, 39, 153, 129, 38, 40, 46, 140, 140, 172, 0, + 251, 41, 244, 153, 56, 180, 67, 22, 40, 33, 9, 111, 79, 11, 215, 49, + 66, 195, 45, 113, 22, 41, 109, 39, 124, 178, 49, 173, 25, 245, 157, 190, + 63, 116, 79, 213, 200, 171, 85, 121, 185, 198, 99, 92, 235, 127, 157, 18, + 45, 201, 187, 193, 140, 79, 33, 65, 24, 11, 175, 105, 233, 47, 242, 36, + 139, 254, 195, 48, 31, 146, 32, 0, 150, 237, 52, 165, 4, 174, 230, 81, + 72, 146, 101, 241, 206, 146, 151, 105, 106, 255, 165, 127, 196, 69, 250, 155, + 248, 177, 254, 232, 30, 109, 169, 33, 76, 112, 72, 214, 254, 113, 170, 234, + 191, 76, 20, 132, 209, 243, 152, 241, 107, 12, 107, 31, 16, 149, 129, 8, + 160, 7, 54, 31, 219, 58, 93, 76, 50, 143, 210, 73, 131, 59, 34, 38, + 88, 9, 217, 193, 206, 147, 54, 244, 11, 240, 180, 243, 123, 68, 124, 81, + 153, 132, 49, 38, 33, 220, 125, 164, 236, 162, 128, 202, 246, 183, 178, 35, + 242, 109, 76, 7, 215, 92, 149, 32, 117, 34, 174, 122, 34, 101, 5, 67, + 79, 24, 48, 75, 194, 8, 12, 98, 113, 36, 13, 79, 16, 94, 249, 110, + 147, 212, 105, 205, 39, 31, 127, 182, 213, 97, 28, 226, 105, 217, 245, 84, + 138, 119, 58, 136, 137, 79, 193, 116, 226, 72, 101, 0, 142, 171, 59, 40, + 203, 158, 100, 187, 137, 8, 9, 125, 233, 16, 241, 192, 135, 4, 72, 132, + 89, 126, 34, 0, 197, 80, 159, 101, 77, 18, 52, 179, 249, 169, 95, 125, + 120, 18, 56, 177, 106, 6, 100, 99, 197, 197, 111, 104, 120, 211, 163, 86, + 224, 106, 157, 48, 112, 84, 232, 171, 172, 220, 107, 136, 118, 170, 105, 16, + 133, 223, 77, 65, 61, 41, 184, 88, 67, 98, 175, 216, 139, 56, 140, 26, + 18, 179, 212, 180, 218, 235, 78, 180, 154, 144, 195, 188, 126, 205, 37, 58, + 203, 223, 248, 156, 87, 139, 176, 77, 244, 117, 77, 148, 85, 187, 142, 119, + 144, 113, 128, 217, 33, 5, 107, 247, 10, 178, 66, 206, 128, 187, 155, 161, + 150, 166, 9, 194, 18, 87, 82, 5, 42, 74, 250, 215, 83, 145, 8, 158, + 182, 156, 82, 161, 19, 87, 92, 77, 14, 7, 208, 23, 8, 13, 59, 57, + 167, 252, 236, 167, 68, 206, 208, 173, 237, 84, 141, 14, 118, 250, 194, 37, + 131, 146, 23, 17, 37, 228, 42, 134, 130, 193, 34, 83, 151, 107, 227, 133, + 189, 157, 96, 73, 176, 115, 205, 111, 159, 89, 182, 43, 180, 27, 36, 57, + 30, 151, 83, 181, 2, 2, 53, 17, 231, 175, 92, 52, 97, 124, 25, 172, + 17, 206, 83, 37, 79, 60, 174, 47, 181, 207, 115, 216, 0, 59, 178, 186, + 222, 154, 48, 10, 203, 237, 168, 102, 67, 97, 12, 80, 164, 196, 36, 102, + 249, 198, 223, 40, 139, 247, 238, 100, 167, 179, 209, 170, 131, 198, 166, 105, + 139, 118, 164, 153, 86, 75, 187, 187, 197, 160, 68, 198, 18, 67, 72, 85, + 158, 8, 198, 13, 38, 133, 227, 47, 6, 64, 250, 136, 178, 128, 108, 116, + 81, 186, 206, 233, 159, 179, 60, 114, 136, 222, 26, 198, 221, 9, 223, 32, + 123, 35, 23, 188, 146, 155, 213, 76, 159, 32, 252, 211, 185, 1, 157, 178, + 135, 227, 248, 103, 157, 213, 189, 148, 107, 135, 236, 254, 236, 112, 211, 216, + 133, 146, 65, 193, 156, 12, 68, 129, 130, 145, 203, 140, 174, 99, 164, 145, + 36, 252, 41, 175, 206, 147, 115, 196, 4, 174, 108, 17, 122, 230, 134, 147, + 226, 163, 123, 125, 195, 16, 122, 59, 157, 243, 224, 222, 35, 75, 158, 165, + 183, 96, 220, 251, 154, 155, 140, 144, 238, 87, 118, 32, 40, 120, 50, 237, + 231, 139, 167, 105, 32, 225, 232, 86, 220, 154, 75, 196, 71, 65, 93, 220, + 61, 119, 51, 177, 246, 221, 145, 96, 123, 19, 25, 236, 101, 58, 161, 73, + 84, 176, 133, 105, 196, 134, 172, 27, 162, 226, 224, 55, 16, 137, 168, 193, + 190, 36, 174, 21, 216, 214, 118, 104, 129, 255, 68, 151, 108, 167, 109, 82, + 66, 183, 246, 156, 70, 234, 152, 129, 21, 156, 244, 102, 179, 68, 253, 171, + 86, 189, 188, 191, 254, 81, 210, 173, 115, 204, 35, 164, 144, 108, 236, 225, + 100, 49, 60, 210, 38, 90, 187, 49, 180, 192, 94, 27, 241, 255, 99, 158, + 7, 237, 83, 24, 236, 15, 188, 123, 165, 197, 98, 230, 62, 46, 224, 117, + 139, 102, 180, 131, 227, 218, 54, 126, 52, 152, 148, 252, 217, 93, 32, 154, + 96, 161, 242, 40, 170, 26, 56, 74, 254, 10, 15, 19, 201, 213, 81, 46, + 158, 233, 148, 163, 223, 116, 67, 170, 168, 17, 52, 115, 222, 60, 24, 251, + 6, 74, 89, 86, 242, 245, 45, 128, 182, 3, 195, 154, 20, 179, 113, 153, + 44, 242, 180, 83, 26, 92, 220, 87, 99, 40, 234, 36, 47, 104, 5, 216, + 15, 75, 28, 250, 13, 84, 199, 155, 151, 61, 58, 214, 142, 173, 215, 72, + 185, 60, 233, 73, 102, 177, 181, 170, 7, 48, 166, 110, 32, 227, 24, 254, + 43, 157, 97, 119, 1, 125, 154, 244, 80, 196, 119, 70, 137, 163, 29, 157, + 21, 96, 40, 77, 149, 43, 89, 115, 78, 66, 67, 78, 130, 122, 141, 108, + 245, 94, 13, 91, 233, 28, 99, 104, 150, 29, 104, 122, 221, 186, 150, 126, + 164, 59, 147, 132, 74, 1, 84, 129, 134, 199, 184, 19, 164, 172, 218, 226, + 69, 96, 187, 3, 219, 55, 20, 36, 43, 220, 131, 166, 139, 173, 189, 7, + 95, 213, 220, 66, 112, 32, 44, 231, 163, 42, 23, 106, 253, 98, 142, 233, + 108, 164, 242, 111, 223, 130, 113, 101, 180, 103, 69, 79, 3, 212, 134, 113, + 14, 252, 41, 247, 87, 188, 147, 176, 171, 218, 249, 176, 197, 157, 118, 13, + 73, 246, 206, 106, 50, 120, 17, 148, 147, 164, 185, 70, 144, 158, 116, 214, + 92, 246, 184, 68, 85, 100, 240, 154, 2, 156, 164, 212, 110, 241, 153, 129, + 7, 222, 203, 157, 48, 94, 103, 89, 110, 197, 102, 10, 76, 234, 22, 12, + 104, 202, 167, 57, 56, 178, 52, 73, 40, 212, 95, 196, 212, 166, 85, 15, + 41, 81, 141, 124, 130, 100, 79, 100, 175, 126, 225, 151, 102, 116, 43, 17, + 190, 116, 116, 79, 51, 59, 243, 149, 11, 121, 3, 234, 103, 221, 234, 201, + 245, 5, 11, 20, 29, 181, 138, 67, 190, 119, 205, 66, 225, 155, 66, 14, + 205, 68, 114, 207, 7, 180, 117, 185, 176, 204, 9, 9, 126, 205, 58, 142, + 28, 136, 232, 53, 149, 237, 169, 44, 185, 78, 143, 99, 153, 143, 187, 157, + 87, 106, 201, 63, 2, 205, 96, 226, 4, 28, 208, 81, 197, 98, 126, 168, + 170, 63, 29, 15, 228, 23, 82, 12, 109, 204, 227, 231, 228, 87, 196, 63, + 117, 68, 31, 206, 19, 177, 225, 66, 233, 244, 58, 185, 208, 188, 153, 253, + 0, 60, 122, 11, 36, 193, 235, 90, 21, 89, 103, 232, 187, 68, 214, 232, + 180, 13, 143, 157, 99, 180, 232, 213, 90, 113, 194, 193, 194, 230, 242, 45, + 135, 51, 201, 80, 171, 128, 144, 150, 184, 193, 211, 22, 74, 186, 176, 237, + 133, 181, 83, 216, 250, 76, 28, 144, 255, 76, 29, 64, 27, 25, 54, 88, + 161, 132, 38, 34, 236, 32, 77, 106, 157, 6, 74, 120, 64, 211, 237, 173, + 164, 29, 22, 107, 236, 9, 67, 136, 70, 87, 153, 52, 245, 162, 52, 213, + 109, 66, 123, 116, 19, 54, 210, 216, 16, 72, 192, 249, 183, 108, 193, 60, + 242, 120, 186, 160, 200, 137, 184, 180, 97, 15, 95, 167, 169, 87, 146, 151, + 83, 244, 178, 11, 114, 231, 59, 246, 175, 29, 229, 95, 166, 199, 244, 74, + 6, 79, 7, 15, 150, 53, 55, 148, 10, 214, 117, 214, 214, 18, 111, 23, + 77, 192, 122, 193, 255, 196, 114, 120, 89, 233, 200, 20, 133, 140, 132, 162, + 136, 45, 10, 216, 110, 169, 138, 221, 15, 114, 80, 66, 207, 159, 89, 31, + 183, 6, 112, 209, 114, 85, 57, 171, 99, 14, 83, 218, 19, 240, 133, 147, + 208, 50, 112, 209, 213, 114, 113, 128, 67, 115, 171, 57, 184, 202, 111, 119, + 128, 8, 204, 133, 137, 179, 216, 142, 74, 57, 86, 75, 192, 237, 228, 108, + 69, 105, 193, 141, 250, 76, 204, 128, 155, 26, 66, 172, 237, 250, 179, 186, + 199, 211, 152, 65, 6, 152, 201, 105, 251, 78, 186, 157, 66, 69, 101, 190, + 17, 230, 96, 168, 156, 29, 7, 59, 250, 141, 145, 141, 234, 100, 149, 39, + 172, 205, 57, 39, 61, 6, 218, 254, 181, 184, 94, 155, 251, 236, 8, 17, + 252, 132, 153, 56, 164, 230, 249, 203, 60, 78, 227, 136, 118, 97, 69, 247, + 170, 83, 230, 125, 104, 85, 239, 19, 220, 15, 148, 251, 249, 196, 138, 38, + 81, 209, 15, 231, 239, 183, 73, 121, 87, 157, 191, 171, 0, 99, 100, 105, + 105, 223, 226, 113, 198, 179, 200, 75, 136, 55, 190, 194, 166, 94, 142, 224, + 39, 193, 163, 138, 3, 203, 220, 34, 118, 216, 34, 142, 111, 227, 241, 205, + 154, 220, 162, 107, 200, 100, 217, 194, 122, 207, 234, 161, 104, 119, 201, 84, + 46, 37, 159, 130, 76, 136, 147, 250, 29, 209, 151, 145, 92, 189, 105, 79, + 101, 117, 4, 209, 229, 171, 22, 168, 11, 210, 160, 120, 158, 218, 39, 129, + 95, 30, 254, 37, 160, 17, 226, 65, 38, 155, 129, 122, 222, 170, 133, 113, + 134, 168, 135, 212, 57, 200, 248, 226, 62, 62, 200, 159, 127, 42, 51, 90, + 49, 28, 134, 6, 226, 227, 159, 163, 142, 179, 173, 151, 168, 47, 106, 150, + 43, 205, 20, 245, 181, 82, 210, 73, 173, 93, 73, 132, 69, 71, 195, 129, + 214, 106, 151, 117, 135, 138, 224, 126, 167, 48, 83, 34, 36, 200, 13, 29, + 239, 80, 11, 224, 146, 30, 165, 79, 231, 209, 119, 168, 138, 217, 100, 202, + 154, 132, 206, 54, 71, 170, 74, 126, 11, 105, 96, 94, 176, 133, 105, 167, + 60, 81, 127, 80, 238, 86, 126, 54, 147, 16, 117, 54, 230, 12, 76, 196, + 8, 177, 11, 61, 177, 113, 30, 40, 18, 26, 18, 55, 37, 74, 94, 243, + 222, 250, 144, 1, 67, 236, 61, 94, 204, 49, 44, 63, 128, 123, 253, 163, + 36, 31, 168, 42, 144, 198, 132, 53, 212, 183, 1, 234, 164, 254, 55, 113, + 19, 28, 184, 210, 113, 4, 95, 146, 92, 164, 152, 120, 176, 218, 237, 134, + 193, 243, 109, 2, 35, 253, 94, 25, 192, 246, 118, 186, 220, 218, 81, 217, + 36, 126, 215, 24, 86, 127, 114, 69, 176, 237, 20, 52, 239, 1, 82, 149, + 90, 227, 216, 108, 176, 100, 41, 68, 64, 97, 13, 13, 10, 132, 104, 252, + 194, 30, 134, 21, 234, 121, 133, 137, 238, 55, 1, 233, 41, 41, 165, 24, + 135, 243, 206, 15, 65, 184, 175, 222, 34, 216, 2, 143, 84, 207, 136, 195, + 96, 7, 114, 230, 244, 158, 69, 30, 62, 183, 157, 58, 157, 248, 35, 163, + 89, 27, 18, 44, 149, 74, 255, 140, 216, 203, 58, 102, 75, 24, 123, 11, + 79, 224, 186, 187, 55, 178, 22, 170, 74, 65, 248, 185, 88, 174, 100, 179, + 42, 147, 165, 94, 149, 106, 1, 14, 49, 135, 110, 240, 201, 36, 145, 118, + 151, 62, 220, 245, 246, 188, 254, 207, 98, 231, 47, 67, 38, 225, 110, 86, + 50, 168, 160, 3, 188, 233, 152, 13, 199, 93, 171, 72, 152, 181, 223, 144, + 105, 206, 64, 198, 51, 125, 118, 168, 107, 110, 42, 87, 126, 137, 100, 52, + 139, 187, 84, 78, 109, 68, 157, 242, 105, 42, 192, 199, 227, 229, 167, 149, + 115, 222, 117, 64, 146, 168, 86, 69, 160, 37, 91, 184, 75, 172, 107, 178, + 205, 113, 109, 197, 143, 177, 69, 241, 131, 191, 103, 112, 145, 194, 234, 152, + 191, 196, 121, 189, 118, 85, 248, 218, 129, 113, 247, 58, 112, 168, 212, 15, + 226, 249, 121, 7, 193, 119, 219, 153, 152, 134, 87, 50, 53, 1, 122, 228, + 133, 70, 218, 235, 176, 226, 181, 228, 247, 171, 237, 208, 93, 219, 210, 204, + 99, 81, 35, 94, 213, 244, 214, 133, 87, 38, 157, 220, 76, 241, 250, 9, + 174, 94, 200, 220, 42, 33, 84, 33, 20, 6, 86, 165, 70, 17, 23, 147, + 58, 74, 222, 31, 41, 174, 132, 226, 158, 2, 97, 151, 118, 118, 199, 237, + 251, 181, 137, 122, 134, 180, 206, 25, 127, 6, 28, 88, 227, 99, 230, 21, + 51, 19, 201, 179, 147, 131, 49, 170, 49, 104, 15, 138, 137, 169, 120, 94, + 205, 80, 43, 230, 239, 124, 165, 225, 36, 228, 209, 108, 204, 135, 125, 157, + 94, 203, 116, 141, 29, 156, 97, 146, 225, 80, 43, 254, 51, 120, 58, 221, + 11, 176, 165, 179, 174, 53, 216, 195, 110, 24, 177, 125, 101, 171, 86, 108, + 182, 14, 91, 146, 246, 127, 249, 192, 221, 143, 211, 90, 9, 12, 130, 246, + 170, 107, 193, 134, 28, 49, 35, 254, 131, 137, 125, 207, 196, 72, 80, 90, + 30, 174, 143, 172, 226, 50, 12, 236, 58, 235, 205, 251, 234, 171, 14, 201, + 232, 131, 230, 212, 162, 143, 189, 179, 44, 100, 224, 49, 15, 155, 170, 228, + 158, 151, 239, 19, 0, 232, 204, 216, 76, 21, 149, 130, 142, 63, 146, 152, + 124, 136, 129, 14, 182, 212, 29, 8, 244, 12, 36, 28, 134, 52, 216, 106, + 229, 107, 150, 8, 223, 247, 117, 229, 251, 216, 158, 228, 97, 240, 148, 228, + 49, 138, 80, 34, 204, 52, 237, 43, 105, 142, 231, 20, 32, 70, 44, 180, + 212, 121, 229, 177, 50, 152, 238, 72, 51, 116, 111, 18, 27, 211, 40, 211, + 97, 226, 18, 155, 21, 216, 166, 165, 37, 234, 56, 121, 165, 159, 197, 87, + 203, 146, 69, 137, 25, 148, 143, 246, 247, 131, 100, 91, 45, 25, 127, 103, + 35, 219, 32, 31, 237, 93, 92, 167, 194, 64, 255, 188, 64, 139, 118, 135, + 212, 56, 216, 167, 102, 36, 220, 109, 21, 147, 92, 78, 8, 65, 213, 179, + 11, 40, 227, 83, 207, 175, 56, 75, 193, 105, 239, 145, 193, 107, 234, 101, + 50, 97, 123, 246, 137, 30, 180, 149, 18, 62, 162, 163, 16, 192, 79, 61, + 222, 25, 35, 181, 13, 10, 90, 25, 216, 76, 219, 117, 100, 244, 159, 172, + 223, 106, 19, 1, 176, 180, 154, 222, 182, 202, 241, 217, 150, 203, 244, 213, + 94, 178, 158, 130, 166, 105, 167, 118, 194, 153, 142, 60, 134, 216, 142, 216, + 254, 2, 7, 54, 26, 197, 25, 138, 74, 39, 101, 107, 168, 110, 24, 58, + 191, 136, 25, 40, 26, 79, 96, 4, 25, 32, 134, 180, 69, 19, 198, 208, + 254, 197, 133, 72, 242, 66, 107, 23, 157, 143, 117, 50, 224, 198, 246, 8, + 19, 49, 213, 159, 9, 201, 160, 158, 200, 59, 145, 119, 110, 58, 190, 132, + 168, 220, 64, 171, 103, 140, 202, 167, 130, 190, 195, 57, 194, 90, 11, 214, + 19, 53, 68, 88, 89, 14, 235, 20, 50, 249, 248, 100, 241, 10, 149, 35, + 93, 4, 84, 62, 75, 41, 223, 81, 56, 18, 14, 101, 224, 40, 118, 53, + 252, 72, 194, 185, 15, 235, 120, 170, 171, 237, 242, 201, 96, 157, 93, 248, + 227, 156, 239, 249, 190, 10, 177, 147, 77, 18, 157, 53, 114, 233, 168, 14, + 28, 80, 50, 89, 248, 127, 156, 98, 193, 111, 202, 38, 248, 60, 243, 240, + 198, 122, 227, 160, 117, 138, 247, 171, 235, 47, 23, 245, 177, 12, 24, 213, + 214, 117, 210, 86, 85, 55, 153, 25, 16, 53, 195, 81, 247, 217, 104, 109, + 170, 63, 79, 169, 38, 150, 42, 167, 206, 230, 51, 109, 62, 202, 205, 164, + 28, 240, 90, 82, 119, 57, 222, 95, 195, 106, 193, 197, 180, 73, 24, 108, + 143, 114, 54, 29, 100, 255, 124, 30, 143, 120, 147, 84, 110, 157, 53, 226, + 104, 117, 65, 60, 187, 173, 94, 59, 132, 121, 145, 188, 220, 105, 4, 48, + 89, 130, 82, 236, 212, 138, 179, 197, 182, 115, 6, 83, 196, 132, 184, 148, + 183, 101, 141, 92, 84, 153, 147, 133, 212, 8, 250, 226, 167, 209, 22, 95, + 44, 103, 243, 27, 111, 105, 128, 110, 88, 110, 190, 229, 81, 26, 219, 229, + 83, 247, 16, 17, 158, 228, 197, 32, 193, 223, 184, 178, 89, 21, 43, 254, + 124, 144, 200, 131, 138, 5, 107, 98, 139, 16, 184, 127, 244, 51, 141, 88, + 178, 132, 205, 239, 123, 14, 34, 2, 244, 238, 154, 230, 146, 87, 15, 20, + 164, 174, 159, 28, 211, 81, 230, 227, 158, 16, 168, 8, 18, 105, 177, 68, + 50, 127, 64, 73, 123, 233, 44, 34, 159, 133, 66, 100, 163, 184, 244, 171, + 240, 235, 230, 160, 137, 131, 200, 230, 189, 136, 137, 240, 110, 253, 0, 250, + 52, 126, 123, 209, 83, 189, 61, 243, 153, 60, 36, 157, 156, 141, 175, 212, + 219, 217, 33, 144, 133, 126, 7, 41, 228, 77, 247, 47, 162, 47, 3, 157, + 32, 219, 149, 138, 51, 181, 65, 242, 51, 76, 185, 51, 5, 188, 216, 33, + 31, 179, 247, 93, 55, 241, 103, 253, 14, 6, 32, 17, 137, 194, 126, 235, + 132, 115, 93, 167, 187, 190, 147, 190, 255, 120, 166, 38, 118, 241, 129, 163, + 37, 39, 155, 142, 37, 147, 134, 221, 136, 99, 114, 152, 250, 143, 53, 104, + 103, 7, 37, 178, 195, 124, 200, 196, 34, 8, 247, 255, 156, 141, 29, 202, + 239, 70, 189, 144, 0, 167, 182, 105, 57, 205, 218, 54, 151, 29, 7, 76, + 7, 84, 20, 246, 185, 216, 93, 21, 96, 25, 115, 176, 38, 180, 177, 224, + 112, 104, 92, 17, 152, 55, 211, 21, 210, 98, 249, 201, 21, 85, 84, 185, + 53, 59, 147, 198, 1, 251, 185, 235, 132, 73, 67, 194, 220, 120, 191, 206, + 73, 53, 158, 237, 102, 41, 23, 133, 14, 81, 47, 204, 9, 142, 124, 180, + 115, 236, 180, 190, 218, 68, 92, 113, 54, 250, 174, 99, 126, 1, 186, 88, + 231, 96, 51, 147, 236, 164, 135, 210, 75, 242, 196, 53, 104, 101, 233, 0, + 129, 173, 53, 118, 42, 188, 139, 187, 251, 143, 37, 222, 198, 168, 194, 103, + 107, 56, 240, 213, 98, 0, 65, 112, 187, 230, 203, 207, 104, 124, 78, 130, + 66, 156, 214, 95, 22, 46, 181, 254, 15, 201, 138, 160, 138, 171, 202, 3, + 169, 187, 110, 58, 43, 218, 62, 112, 49, 206, 186, 161, 31, 140, 183, 84, + 143, 250, 217, 123, 9, 210, 87, 1, 208, 77, 143, 33, 6, 237, 173, 108, + 187, 137, 131, 148, 145, 22, 123, 142, 146, 156, 223, 61, 124, 151, 57, 17, + 88, 139, 56, 8, 26, 205, 163, 193, 72, 201, 209, 220, 215, 97, 172, 73, + 99, 139, 111, 125, 94, 196, 78, 235, 224, 103, 38, 237, 9, 142, 131, 229, + 45, 247, 172, 219, 29, 102, 67, 124, 171, 113, 2, 85, 148, 56, 150, 227, + 45, 147, 200, 171, 42, 244, 128, 106, 2, 47, 245, 211, 163, 240, 41, 86, + 50, 70, 44, 91, 166, 247, 110, 234, 138, 152, 4, 100, 49, 248, 198, 51, + 124, 253, 126, 122, 30, 165, 0, 183, 248, 65, 30, 156, 161, 52, 164, 76, + 44, 198, 99, 20, 24, 97, 93, 232, 104, 51, 200, 0, 153, 67, 93, 172, + 94, 217, 127, 34, 29, 64, 149, 41, 78, 211, 63, 188, 61, 102, 2, 127, + 166, 194, 5, 59, 203, 5, 224, 68, 250, 58, 202, 236, 218, 235, 168, 0, + 205, 82, 53, 99, 51, 144, 0, 140, 45, 46, 213, 207, 17, 221, 47, 85, + 211, 87, 2, 35, 167, 236, 191, 70, 147, 201, 200, 69, 1, 228, 136, 243, + 122, 253, 34, 201, 92, 90, 194, 8, 119, 197, 197, 178, 157, 207, 170, 147, + 232, 5, 200, 241, 6, 27, 120, 242, 232, 163, 26, 234, 230, 50, 214, 194, + 125, 135, 62, 28, 118, 24, 155, 39, 166, 250, 204, 189, 169, 94, 110, 81, + 222, 81, 127, 71, 49, 176, 178, 37, 63, 219, 72, 0, 100, 255, 201, 70, + 177, 208, 81, 101, 177, 31, 130, 187, 196, 119, 161, 217, 207, 216, 59, 106, + 15, 56, 134, 229, 99, 68, 73, 215, 9, 25, 119, 82, 88, 19, 184, 42, + 38, 40, 176, 6, 34, 167, 249, 143, 6, 216, 128, 139, 75, 3, 229, 126, + 121, 187, 68, 219, 187, 99, 154, 175, 240, 86, 75, 40, 133, 146, 223, 105, + 220, 83, 126, 90, 206, 136, 102, 199, 36, 217, 56, 78, 226, 138, 59, 142, + 223, 68, 175, 191, 83, 224, 208, 195, 2, 102, 168, 194, 158, 231, 143, 162, + 83, 92, 93, 238, 12, 231, 142, 41, 106, 66, 178, 68, 83, 155, 24, 102, + 150, 112, 1, 27, 175, 239, 85, 175, 61, 75, 157, 245, 121, 62, 171, 217, + 55, 218, 86, 45, 10, 228, 203, 193, 216, 90, 142, 109, 232, 168, 17, 149, + 145, 169, 199, 134, 194, 110, 104, 66, 130, 215, 179, 205, 6, 183, 93, 47, + 131, 8, 104, 12, 169, 92, 69, 43, 193, 77, 223, 238, 36, 15, 59, 136, + 95, 87, 196, 169, 35, 118, 252, 19, 6, 247, 172, 219, 159, 109, 118, 154, + 10, 199, 227, 164, 36, 85, 27, 37, 52, 149, 85, 107, 134, 203, 39, 112, + 63, 235, 229, 225, 141, 127, 46, 188, 125, 48, 183, 137, 79, 157, 251, 128, + 214, 29, 60, 192, 43, 20, 22, 77, 62, 5, 229, 201, 61, 217, 181, 68, + 161, 232, 220, 189, 206, 170, 48, 199, 251, 10, 93, 153, 112, 35, 81, 174, + 17, 220, 54, 183, 4, 229, 14, 231, 33, 14, 63, 121, 125, 205, 101, 110, + 255, 145, 55, 130, 56, 4, 236, 171, 27, 10, 130, 188, 115, 125, 104, 178, + 41, 100, 48, 200, 231, 41, 156, 32, 125, 22, 167, 209, 221, 201, 63, 165, + 210, 15, 14, 83, 162, 45, 176, 131, 195, 34, 145, 120, 155, 67, 82, 254, + 231, 179, 149, 97, 4, 84, 30, 62, 140, 39, 235, 91, 145, 92, 89, 87, + 96, 144, 96, 223, 153, 0, 28, 117, 238, 168, 40, 11, 140, 197, 162, 172, + 72, 23, 120, 153, 147, 195, 6, 39, 36, 54, 174, 202, 182, 74, 232, 30, + 240, 10, 130, 188, 127, 2, 48, 68, 9, 191, 245, 176, 249, 169, 19, 21, + 154, 45, 249, 114, 137, 223, 190, 252, 87, 36, 85, 242, 96, 21, 234, 18, + 157, 108, 86, 179, 103, 87, 149, 121, 231, 19, 111, 157, 154, 171, 158, 128, + 68, 253, 157, 146, 9, 11, 82, 101, 218, 181, 37, 73, 31, 19, 122, 211, + 104, 102, 172, 244, 119, 94, 235, 143, 241, 113, 24, 211, 132, 227, 169, 254, + 60, 118, 45, 122, 177, 97, 161, 170, 233, 212, 139, 23, 179, 61, 117, 175, + 126, 18, 119, 242, 14, 67, 254, 147, 62, 61, 58, 54, 42, 75, 134, 163, + 134, 56, 20, 222, 1, 199, 168, 38, 142, 114, 14, 84, 106, 218, 24, 245, + 129, 59, 86, 217, 80, 79, 119, 218, 53, 136, 124, 63, 90, 179, 205, 112, + 192, 116, 186, 223, 65, 52, 109, 169, 196, 209, 73, 239, 124, 224, 15, 78, + 134, 164, 65, 189, 58, 22, 166, 57, 64, 104, 185, 101, 43, 231, 254, 145, + 156, 74, 38, 201, 121, 28, 25, 221, 129, 82, 26, 14, 36, 32, 158, 208, + 70, 2, 201, 70, 190, 208, 246, 54, 239, 158, 140, 212, 225, 209, 177, 86, + 31, 32, 45, 93, 207, 255, 12, 176, 154, 217, 193, 166, 61, 241, 53, 80, + 37, 214, 34, 65, 207, 114, 163, 132, 116, 133, 63, 217, 234, 5, 111, 188, + 79, 1, 110, 88, 156, 17, 242, 1, 138, 105, 144, 213, 123, 212, 7, 164, + 200, 175, 161, 145, 108, 104, 174, 202, 202, 35, 153, 88, 138, 105, 58, 143, + 57, 227, 90, 38, 189, 38, 66, 80, 222, 174, 7, 202, 57, 236, 239, 104, + 51, 26, 252, 140, 2, 74, 4, 163, 211, 199, 202, 185, 65, 203, 13, 210, + 69, 228, 115, 31, 100, 143, 189, 100, 228, 209, 107, 55, 72, 150, 255, 144, + 232, 155, 15, 42, 18, 149, 49, 207, 32, 148, 178, 112, 254, 67, 51, 14, + 217, 41, 203, 217, 205, 101, 223, 161, 148, 33, 92, 164, 250, 91, 80, 251, + 104, 157, 225, 172, 18, 245, 5, 54, 30, 8, 254, 109, 3, 202, 215, 179, + 161, 236, 147, 104, 254, 232, 217, 124, 178, 1, 206, 38, 168, 77, 8, 112, + 234, 154, 162, 94, 3, 90, 94, 114, 137, 115, 42, 98, 202, 0, 214, 202, + 65, 93, 52, 179, 123, 74, 86, 10, 171, 211, 171, 44, 226, 56, 13, 163, + 7, 146, 57, 253, 115, 93, 156, 132, 119, 146, 107, 98, 218, 19, 195, 5, + 195, 190, 231, 218, 143, 48, 65, 102, 92, 0, 244, 108, 148, 144, 214, 99, + 128, 208, 85, 124, 5, 75, 38, 131, 93, 38, 21, 170, 24, 105, 170, 135, + 152, 21, 38, 191, 251, 88, 178, 62, 84, 177, 239, 61, 156, 63, 47, 195, + 117, 159, 198, 182, 126, 216, 103, 165, 158, 51, 70, 34, 33, 241, 216, 11, + 50, 152, 157, 100, 30, 66, 147, 88, 38, 17, 251, 19, 182, 71, 65, 199, + 150, 215, 188, 188, 80, 83, 2, 83, 73, 183, 251, 85, 101, 25, 173, 50, + 243, 138, 194, 98, 209, 104, 219, 25, 45, 111, 172, 115, 238, 149, 4, 205, + 123, 112, 218, 192, 247, 102, 191, 30, 225, 230, 36, 188, 219, 220, 19, 213, + 127, 226, 227, 17, 90, 216, 88, 129, 249, 230, 91, 42, 111, 102, 45, 42, + 175, 161, 188, 195, 184, 238, 57, 69, 88, 168, 167, 23, 64, 47, 201, 51, + 79, 65, 117, 254, 146, 100, 8, 30, 209, 42, 138, 132, 209, 241, 66, 249, + 228, 192, 48, 21, 75, 202, 123, 99, 76, 87, 34, 99, 32, 224, 140, 94, + 90, 178, 47, 165, 23, 227, 92, 218, 45, 44, 104, 9, 23, 94, 254, 195, + 16, 12, 105, 135, 48, 225, 7, 139, 148, 199, 157, 139, 243, 71, 254, 15, + 64, 143, 140, 3, 221, 218, 117, 118, 34, 177, 156, 50, 220, 99, 219, 4, + 247, 244, 16, 100, 51, 73, 85, 181, 24, 127, 102, 173, 238, 205, 143, 68, + 63, 44, 197, 106, 165, 150, 11, 244, 198, 36, 101, 10, 79, 207, 183, 214, + 228, 226, 226, 235, 77, 11, 175, 80, 90, 197, 35, 99, 7, 121, 208, 236, + 141, 171, 176, 158, 219, 162, 166, 168, 147, 2, 131, 180, 57, 229, 106, 63, + 194, 250, 21, 63, 152, 16, 109, 20, 208, 227, 225, 10, 22, 2, 223, 128, + 89, 100, 47, 101, 165, 0, 147, 198, 47, 109, 94, 113, 183, 101, 113, 248, + 79, 21, 26, 141, 176, 52, 118, 71, 143, 174, 194, 248, 199, 194, 245, 105, + 112, 92, 180, 22, 184, 218, 78, 192, 41, 17, 171, 143, 203, 2, 81, 178, + 177, 138, 101, 113, 190, 77, 70, 73, 85, 228, 194, 2, 70, 191, 54, 43, + 188, 233, 27, 135, 140, 127, 10, 59, 38, 86, 226, 127, 166, 132, 69, 21, + 200, 107, 33, 89, 24, 152, 88, 90, 75, 144, 236, 44, 10, 121, 139, 169, + 113, 127, 104, 227, 164, 145, 69, 196, 233, 237, 127, 132, 204, 244, 178, 247, + 191, 207, 63, 135, 214, 135, 213, 151, 44, 43, 190, 32, 241, 221, 118, 81, + 145, 43, 29, 244, 239, 78, 245, 115, 229, 178, 255, 147, 16, 149, 255, 154, + 217, 226, 234, 99, 247, 146, 209, 42, 9, 74, 220, 199, 178, 165, 246, 188, + 22, 51, 136, 38, 63, 125, 45, 108, 190, 111, 72, 248, 57, 16, 107, 120, + 245, 158, 215, 136, 9, 25, 61, 162, 148, 109, 112, 193, 56, 81, 121, 143, + 208, 225, 20, 130, 245, 12, 81, 156, 189, 102, 23, 51, 135, 76, 205, 59, + 197, 152, 35, 80, 127, 168, 223, 48, 20, 104, 57, 69, 132, 53, 72, 220, + 161, 178, 219, 33, 37, 245, 58, 199, 17, 246, 39, 2, 84, 251, 20, 62, + 21, 56, 209, 143, 149, 24, 68, 59, 17, 240, 215, 95, 195, 188, 231, 97, + 41, 32, 98, 57, 107, 172, 90, 159, 132, 150, 226, 75, 151, 144, 12, 111, + 6, 253, 112, 213, 28, 179, 232, 233, 73, 139, 84, 232, 204, 0, 148, 77, + 48, 183, 37, 213, 67, 195, 211, 206, 12, 110, 212, 180, 201, 229, 77, 7, + 48, 221, 44, 102, 23, 168, 145, 200, 77, 103, 7, 173, 247, 84, 110, 123, + 23, 5, 145, 154, 124, 95, 103, 89, 78, 136, 74, 47, 136, 86, 135, 250, + 60, 228, 64, 78, 228, 172, 111, 204, 89, 144, 119, 8, 248, 81, 70, 113, + 89, 113, 50, 70, 124, 182, 58, 179, 77, 197, 160, 136, 41, 195, 19, 163, + 222, 23, 34, 70, 203, 156, 137, 209, 146, 213, 112, 210, 203, 138, 236, 36, + 24, 57, 106, 75, 115, 112, 43, 229, 239, 154, 133, 160, 211, 36, 241, 229, + 94, 110, 224, 182, 162, 85, 189, 20, 125, 9, 26, 137, 185, 177, 14, 138, + 5, 225, 132, 174, 244, 209, 187, 92, 140, 29, 158, 111, 150, 8, 32, 99, + 99, 142, 213, 19, 101, 164, 64, 190, 61, 219, 198, 118, 246, 217, 110, 173, + 248, 24, 100, 216, 190, 118, 198, 209, 64, 238, 205, 176, 46, 116, 131, 103, + 243, 148, 123, 69, 136, 144, 46, 112, 112, 162, 219, 21, 205, 136, 193, 152, + 96, 134, 16, 22, 146, 190, 194, 19, 119, 47, 44, 67, 131, 166, 109, 215, + 159, 90, 88, 212, 11, 71, 235, 55, 31, 4, 113, 172, 187, 169, 10, 144, + 169, 108, 79, 145, 7, 29, 24, 221, 230, 28, 113, 32, 190, 160, 67, 40, + 43, 107, 222, 221, 175, 180, 200, 217, 15, 128, 253, 206, 203, 106, 167, 163, + 89, 29, 28, 247, 240, 14, 121, 133, 218, 154, 167, 77, 98, 149, 151, 145, + 4, 78, 232, 135, 195, 121, 157, 216, 178, 211, 243, 201, 71, 220, 150, 119, + 74, 71, 110, 200, 234, 100, 105, 248, 47, 25, 35, 1, 241, 166, 6, 88, + 41, 246, 176, 181, 21, 75, 150, 20, 227, 19, 64, 226, 209, 194, 121, 174, + 240, 219, 133, 253, 161, 146, 230, 69, 122, 42, 165, 82, 78, 45, 185, 61, + 12, 14, 148, 13, 119, 155, 157, 28, 90, 226, 119, 9, 201, 199, 64, 93, + 120, 115, 138, 156, 235, 123, 52, 111, 149, 48, 73, 181, 204, 181, 10, 157, + 16, 55, 100, 243, 10, 29, 159, 139, 88, 16, 1, 31, 201, 242, 2, 237, + 186, 181, 217, 139, 102, 205, 119, 197, 201, 221, 108, 205, 171, 54, 109, 31, + 76, 199, 28, 160, 214, 14, 201, 25, 211, 189, 144, 44, 69, 70, 205, 79, + 150, 149, 108, 23, 8, 171, 60, 18, 127, 161, 41, 71, 239, 168, 89, 140, + 49, 149, 157, 109, 232, 141, 227, 239, 247, 114, 174, 129, 19, 252, 130, 74, + 202, 224, 73, 122, 246, 47, 147, 8, 37, 60, 253, 101, 11, 171, 160, 39, + 92, 180, 183, 40, 254, 233, 117, 200, 139, 37, 140, 28, 35, 8, 10, 40, + 167, 247, 248, 84, 215, 58, 170, 2, 7, 1, 69, 214, 10, 7, 233, 209, + 181, 212, 34, 68, 46, 141, 198, 137, 248, 45, 130, 97, 123, 104, 141, 17, + 126, 7, 199, 55, 194, 160, 69, 39, 13, 70, 41, 63, 205, 99, 1, 69, + 46, 92, 77, 56, 20, 247, 224, 226, 60, 153, 81, 180, 91, 159, 156, 27, + 119, 114, 126, 210, 26, 123, 165, 204, 237, 81, 75, 130, 45, 60, 0, 155, + 11, 125, 27, 202, 35, 230, 101, 164, 86, 117, 226, 23, 171, 253, 222, 223, + 38, 104, 224, 124, 92, 251, 110, 145, 247, 198, 158, 25, 172, 84, 49, 87, + 1, 168, 95, 124, 146, 5, 46, 179, 198, 235, 69, 200, 63, 212, 59, 110, + 52, 195, 54, 71, 169, 234, 189, 58, 180, 149, 194, 10, 118, 99, 66, 66, + 123, 192, 248, 51, 237, 129, 10, 143, 94, 55, 135, 247, 56, 163, 40, 139, + 150, 192, 142, 64, 169, 90, 42, 116, 228, 62, 67, 130, 212, 212, 23, 210, + 182, 95, 109, 224, 185, 255, 156, 102, 184, 171, 42, 98, 217, 218, 27, 80, + 171, 125, 49, 233, 16, 238, 42, 102, 61, 95, 180, 49, 192, 67, 112, 143, + 106, 145, 185, 239, 180, 181, 120, 24, 127, 215, 233, 123, 235, 104, 228, 248, + 223, 90, 211, 211, 76, 179, 198, 253, 220, 171, 247, 171, 11, 237, 17, 249, + 81, 122, 111, 255, 213, 120, 167, 192, 149, 102, 7, 204, 86, 107, 156, 83, + 174, 18, 237, 143, 85, 76, 245, 189, 86, 90, 118, 69, 100, 140, 121, 17, + 255, 17, 209, 144, 90, 3, 191, 201, 134, 108, 0, 196, 133, 153, 39, 248, + 138, 215, 73, 18, 21, 140, 172, 178, 154, 194, 170, 45, 112, 113, 213, 36, + 155, 0, 30, 213, 186, 39, 6, 241, 92, 111, 139, 52, 84, 58, 218, 187, + 60, 123, 113, 190, 185, 89, 242, 248, 221, 238, 173, 145, 214, 237, 133, 101, + 6, 143, 188, 116, 13, 189, 205, 203, 147, 140, 215, 175, 38, 99, 77, 54, + 98, 146, 54, 101, 40, 206, 175, 26, 195, 33, 63, 20, 210, 96, 227, 125, + 108, 230, 179, 123, 81, 135, 183, 132, 216, 56, 223, 197, 141, 158, 114, 228, + 67, 172, 95, 76, 69, 212, 188, 244, 12, 16, 158, 119, 106, 44, 39, 36, + 38, 164, 173, 182, 172, 210, 176, 19, 125, 6, 36, 138, 77, 65, 219, 30, + 45, 167, 21, 125, 49, 69, 173, 23, 242, 246, 25, 155, 194, 161, 140, 125, + 97, 153, 68, 120, 114, 23, 243, 242, 192, 129, 68, 88, 43, 161, 33, 152, + 130, 232, 179, 70, 156, 219, 198, 1, 135, 3, 178, 49, 92, 30, 125, 185, + 39, 185, 69, 143, 30, 180, 113, 109, 233, 156, 101, 82, 239, 142, 58, 234, + 151, 67, 2, 140, 198, 7, 180, 167, 33, 168, 131, 213, 157, 139, 43, 208, + 27, 217, 245, 115, 0, 59, 155, 69, 236, 209, 101, 139, 211, 247, 2, 41, + 113, 222, 7, 2, 109, 61, 232, 215, 145, 18, 202, 158, 187, 136, 54, 190, + 169, 13, 59, 204, 117, 37, 160, 6, 121, 200, 9, 189, 31, 0, 251, 78, + 223, 43, 122, 5, 42, 24, 74, 247, 241, 68, 42, 49, 28, 153, 3, 40, + 166, 47, 55, 83, 186, 236, 69, 132, 91, 115, 132, 26, 214, 160, 51, 161, + 232, 147, 172, 175, 144, 53, 58, 241, 1, 245, 53, 126, 211, 121, 98, 228, + 65, 166, 9, 186, 93, 111, 249, 87, 109, 85, 218, 177, 160, 225, 99, 131, + 167, 173, 36, 10, 121, 121, 98, 249, 99, 68, 128, 159, 217, 207, 65, 52, + 247, 53, 58, 135, 11, 76, 238, 101, 162, 166, 100, 126, 136, 157, 43, 172, + 186, 157, 138, 2, 132, 141, 165, 152, 92, 234, 3, 92, 81, 111, 83, 239, + 234, 204, 152, 240, 74, 198, 42, 56, 131, 104, 96, 83, 207, 109, 30, 185, + 45, 242, 2, 155, 47, 18, 111, 119, 57, 239, 7, 88, 45, 86, 239, 10, + 178, 146, 58, 248, 96, 166, 234, 253, 202, 224, 111, 120, 216, 70, 205, 29, + 154, 232, 216, 165, 222, 76, 153, 46, 5, 143, 71, 197, 175, 198, 127, 231, + 119, 110, 47, 128, 61, 134, 41, 115, 101, 3, 35, 127, 201, 12, 152, 1, + 163, 41, 91, 233, 10, 230, 150, 44, 140, 234, 164, 184, 214, 218, 114, 23, + 221, 163, 57, 2, 5, 147, 66, 223, 90, 238, 136, 95, 138, 116, 27, 91, + 223, 52, 243, 246, 183, 215, 166, 170, 169, 8, 140, 91, 173, 160, 160, 105, + 69, 241, 31, 33, 33, 148, 215, 67, 130, 181, 1, 114, 104, 206, 192, 195, + 247, 229, 99, 84, 29, 2, 132, 146, 191, 243, 37, 36, 46, 176, 164, 68, + 84, 121, 159, 6, 160, 195, 170, 43, 128, 130, 165, 44, 157, 83, 173, 182, + 93, 90, 202, 227, 133, 140, 39, 203, 202, 2, 49, 96, 178, 190, 147, 15, + 99, 71, 216, 166, 97, 130, 87, 4, 149, 23, 107, 246, 216, 213, 222, 64, + 41, 215, 37, 211, 21, 53, 90, 130, 165, 181, 188, 87, 70, 8, 53, 114, + 227, 18, 192, 19, 200, 195, 83, 228, 1, 171, 202, 229, 92, 92, 227, 48, + 251, 31, 198, 59, 162, 119, 9, 75, 115, 30, 127, 8, 89, 99, 249, 86, + 152, 198, 53, 207, 82, 251, 68, 82, 247, 21, 214, 18, 246, 118, 81, 94, + 240, 34, 174, 233, 205, 204, 71, 0, 254, 24, 178, 166, 248, 12, 70, 187, + 163, 168, 95, 23, 108, 156, 210, 244, 198, 216, 54, 32, 83, 158, 121, 26, + 116, 252, 122, 73, 188, 134, 154, 180, 229, 139, 102, 2, 8, 171, 201, 5, + 187, 57, 35, 254, 35, 19, 161, 16, 88, 215, 158, 148, 249, 201, 65, 177, + 144, 69, 138, 161, 220, 255, 190, 223, 43, 181, 11, 158, 103, 193, 14, 21, + 49, 16, 40, 223, 155, 12, 164, 23, 31, 15, 20, 238, 131, 85, 181, 80, + 149, 128, 196, 123, 155, 236, 9, 94, 252, 182, 54, 62, 215, 115, 115, 224, + 242, 141, 137, 238, 115, 101, 107, 65, 202, 79, 79, 27, 239, 29, 154, 19, + 18, 4, 185, 144, 191, 107, 92, 29, 38, 248, 142, 81, 109, 64, 161, 23, + 73, 93, 31, 114, 51, 81, 98, 209, 69, 27, 43, 22, 4, 168, 88, 60, + 149, 89, 100, 82, 122, 95, 21, 38, 97, 185, 87, 66, 82, 16, 242, 109, + 100, 94, 164, 6, 73, 130, 76, 137, 218, 226, 166, 35, 21, 156, 72, 253, + 148, 228, 142, 134, 41, 145, 15, 144, 215, 187, 120, 239, 195, 203, 44, 250, + 46, 72, 181, 43, 255, 81, 247, 100, 195, 248, 208, 115, 141, 32, 190, 131, + 77, 230, 220, 54, 197, 60, 22, 115, 177, 116, 250, 0, 60, 144, 128, 68, + 245, 231, 199, 216, 17, 216, 227, 120, 221, 68, 233, 236, 202, 121, 189, 237, + 149, 60, 244, 130, 250, 169, 70, 101, 147, 8, 49, 248, 61, 207, 202, 148, + 228, 87, 234, 117, 238, 52, 92, 118, 148, 203, 206, 175, 75, 64, 215, 57, + 70, 196, 52, 62, 29, 116, 241, 185, 96, 131, 201, 219, 16, 3, 188, 159, + 129, 134, 11, 138, 13, 3, 72, 193, 183, 236, 91, 171, 161, 52, 166, 23, + 254, 118, 238, 180, 55, 215, 165, 163, 154, 202, 27, 61, 150, 31, 12, 1, + 249, 0, 12, 29, 132, 213, 168, 105, 53, 112, 54, 2, 236, 131, 230, 3, + 211, 69, 243, 233, 173, 145, 105, 27, 18, 252, 224, 5, 46, 18, 233, 96, + 237, 143, 52, 67, 158, 30, 242, 151, 98, 148, 208, 60, 143, 14, 245, 250, + 185, 151, 111, 147, 145, 197, 165, 233, 18, 178, 240, 83, 228, 213, 237, 58, + 20, 152, 249, 241, 250, 204, 15, 167, 97, 242, 6, 228, 117, 133, 2, 199, + 220, 212, 239, 206, 104, 231, 145, 33, 17, 150, 223, 126, 173, 223, 148, 21, + 228, 41, 63, 37, 19, 102, 73, 95, 196, 40, 151, 2, 19, 239, 182, 22, + 178, 165, 242, 159, 208, 226, 72, 179, 201, 109, 157, 18, 230, 130, 221, 89, + 173, 242, 170, 11, 146, 20, 135, 112, 2, 202, 30, 25, 106, 151, 52, 223, + 1, 3, 18, 151, 74, 113, 49, 186, 112, 160, 121, 38, 233, 155, 188, 237, + 251, 178, 8, 200, 120, 134, 152, 22, 232, 250, 219, 237, 157, 23, 134, 158, + 122, 202, 120, 89, 248, 68, 46, 184, 180, 93, 84, 85, 177, 236, 62, 50, + 103, 62, 81, 105, 33, 15, 97, 203, 192, 132, 219, 70, 203, 104, 162, 98, + 179, 224, 44, 101, 221, 84, 176, 97, 77, 84, 45, 255, 227, 80, 107, 45, + 70, 106, 68, 206, 134, 182, 205, 255, 235, 44, 131, 81, 126, 142, 30, 130, + 87, 133, 227, 15, 200, 194, 5, 230, 230, 169, 65, 116, 104, 193, 196, 214, + 18, 199, 56, 114, 5, 7, 189, 158, 32, 119, 53, 93, 169, 172, 141, 223, + 71, 194, 204, 221, 237, 118, 16, 198, 169, 10, 38, 156, 152, 76, 185, 73, + 15, 227, 118, 57, 149, 160, 14, 158, 18, 139, 117, 249, 142, 12, 175, 252, + 9, 202, 65, 196, 23, 211, 174, 169, 85, 244, 154, 239, 28, 199, 196, 171, + 241, 27, 140, 222, 54, 25, 229, 69, 102, 134, 125, 235, 246, 156, 41, 75, + 212, 225, 169, 207, 88, 246, 136, 176, 27, 40, 205, 228, 239, 24, 217, 42, + 212, 63, 187, 75, 60, 197, 97, 245, 3, 35, 243, 128, 36, 129, 145, 31, + 27, 193, 20, 122, 116, 143, 130, 159, 80, 203, 253, 233, 66, 118, 92, 177, + 83, 55, 141, 189, 115, 240, 125, 107, 8, 221, 237, 171, 24, 183, 220, 174, + 149, 51, 81, 221, 187, 233, 21, 116, 37, 88, 123, 20, 208, 201, 141, 155, + 136, 148, 64, 14, 102, 204, 248, 173, 249, 61, 75, 253, 199, 46, 192, 138, + 79, 83, 161, 127, 235, 140, 173, 158, 127, 232, 77, 17, 45, 207, 154, 51, + 79, 57, 184, 22, 220, 225, 61, 233, 188, 119, 221, 254, 87, 105, 151, 29, + 156, 162, 18, 202, 244, 36, 105, 24, 240, 195, 198, 39, 31, 155, 135, 62, + 220, 180, 53, 70, 121, 254, 234, 194, 79, 177, 181, 75, 23, 20, 217, 209, + 107, 100, 175, 83, 25, 212, 62, 11, 108, 33, 144, 17, 150, 176, 225, 86, + 54, 190, 8, 82, 150, 219, 80, 72, 75, 100, 197, 72, 95, 174, 189, 158, + 109, 146, 103, 67, 101, 165, 191, 178, 148, 32, 173, 147, 195, 145, 27, 119, + 126, 46, 186, 120, 226, 41, 209, 51, 171, 29, 4, 244, 184, 209, 92, 159, + 221, 122, 163, 30, 246, 68, 8, 190, 146, 143, 159, 116, 211, 83, 247, 90, + 241, 193, 10, 58, 250, 60, 69, 182, 204, 181, 207, 107, 37, 104, 150, 14, + 69, 55, 20, 7, 158, 96, 202, 248, 68, 220, 209, 132, 133, 164, 58, 175, + 103, 166, 1, 174, 0, 32, 182, 13, 199, 83, 48, 148, 52, 198, 19, 135, + 58, 46, 109, 164, 49, 199, 26, 109, 132, 19, 46, 118, 59, 27, 202, 73, + 4, 1, 22, 183, 163, 247, 45, 96, 206, 43, 239, 186, 131, 5, 61, 198, + 46, 99, 31, 89, 194, 241, 207, 170, 80, 250, 72, 225, 89, 154, 151, 165, + 171, 42, 59, 58, 68, 73, 178, 88, 153, 111, 247, 233, 19, 130, 51, 194, + 18, 142, 129, 52, 252, 167, 183, 238, 99, 198, 85, 134, 20, 114, 94, 90, + 7, 223, 147, 178, 135, 156, 216, 69, 14, 42, 181, 232, 203, 63, 239, 213, + 42, 225, 189, 223, 15, 238, 219, 62, 218, 15, 210, 141, 184, 226, 11, 228, + 9, 40, 37, 118, 26, 194, 213, 220, 99, 247, 7, 137, 187, 61, 64, 56, + 86, 169, 143, 224, 135, 166, 4, 28, 55, 87, 216, 45, 56, 39, 37, 181, + 234, 38, 4, 241, 184, 43, 134, 108, 245, 247, 230, 99, 162, 95, 214, 92, + 191, 83, 38, 152, 241, 38, 33, 32, 38, 92, 222, 228, 138, 11, 143, 135, + 83, 181, 140, 99, 9, 252, 123, 215, 212, 81, 108, 71, 2, 159, 246, 82, + 118, 186, 48, 69, 212, 147, 218, 61, 183, 170, 130, 233, 227, 145, 101, 156, + 20, 106, 128, 214, 238, 12, 163, 59, 152, 250, 112, 173, 42, 5, 1, 68, + 35, 52, 13, 198, 121, 11, 117, 16, 126, 143, 54, 184, 205, 44, 238, 47, + 218, 75, 112, 228, 183, 55, 22, 189, 35, 146, 27, 44, 229, 190, 241, 110, + 42, 152, 12, 141, 131, 183, 84, 31, 40, 185, 108, 176, 173, 247, 217, 214, + 155, 108, 176, 152, 201, 201, 185, 7, 227, 187, 87, 71, 45, 98, 224, 159, + 125, 230, 132, 19, 233, 98, 174, 93, 80, 245, 32, 94, 253, 35, 150, 68, + 176, 83, 50, 127, 196, 149, 176, 191, 136, 194, 84, 228, 106, 238, 47, 206, + 110, 204, 9, 116, 136, 230, 249, 90, 215, 160, 51, 151, 61, 92, 187, 82, + 129, 101, 75, 238, 22, 166, 132, 86, 183, 113, 149, 215, 39, 242, 214, 148, + 71, 168, 236, 20, 105, 249, 219, 23, 101, 63, 92, 173, 40, 126, 253, 145, + 161, 9, 72, 60, 215, 59, 155, 228, 255, 201, 193, 60, 129, 51, 29, 207, + 237, 43, 145, 161, 41, 115, 98, 19, 138, 253, 66, 232, 233, 186, 79, 114, + 1, 164, 184, 14, 61, 151, 198, 60, 247, 115, 5, 176, 132, 201, 245, 60, + 21, 238, 60, 133, 186, 18, 154, 89, 170, 23, 102, 2, 111, 147, 25, 208, + 152, 173, 13, 58, 125, 181, 115, 218, 196, 107, 173, 192, 60, 94, 140, 254, + 83, 80, 214, 220, 245, 254, 250, 39, 202, 132, 142, 84, 16, 199, 20, 129, + 159, 24, 18, 123, 143, 157, 176, 199, 173, 56, 169, 222, 252, 63, 27, 242, + 137, 138, 253, 143, 4, 209, 124, 86, 243, 170, 152, 121, 231, 24, 238, 35, + 113, 27, 205, 59, 153, 161, 234, 65, 153, 237, 97, 197, 98, 216, 129, 30, + 174, 211, 193, 167, 102, 229, 240, 198, 85, 193, 253, 73, 118, 185, 63, 3, + 227, 165, 139, 38, 109, 214, 108, 253, 48, 227, 253, 219, 1, 226, 89, 47, + 145, 86, 8, 234, 146, 159, 230, 108, 212, 111, 112, 129, 121, 28, 164, 105, + 138, 143, 106, 132, 254, 202, 177, 171, 123, 38, 162, 112, 97, 88, 221, 95, + 5, 161, 222, 76, 234, 253, 239, 231, 13, 62, 243, 80, 164, 204, 67, 229, + 43, 103, 152, 30, 131, 240, 218, 184, 149, 161, 234, 124, 238, 126, 33, 234, + 133, 1, 201, 113, 176, 190, 231, 215, 99, 64, 219, 224, 29, 217, 23, 232, + 185, 215, 56, 14, 128, 31, 227, 227, 80, 213, 239, 224, 36, 144, 26, 243, + 36, 181, 129, 69, 104, 55, 42, 212, 27, 252, 74, 173, 196, 255, 96, 153, + 53, 3, 99, 13, 167, 244, 183, 92, 231, 140, 210, 116, 98, 36, 187, 126, + 84, 77, 144, 109, 126, 138, 53, 237, 100, 96, 209, 68, 204, 61, 104, 246, + 64, 35, 98, 99, 82, 152, 68, 118, 51, 82, 101, 136, 76, 149, 234, 135, + 110, 37, 167, 154, 17, 145, 150, 148, 89, 184, 123, 108, 255, 2, 49, 98, + 101, 125, 88, 110, 2, 146, 130, 120, 212, 249, 21, 164, 164, 161, 47, 201, + 70, 114, 46, 149, 0, 88, 142, 60, 228, 58, 181, 175, 207, 222, 199, 81, + 135, 121, 200, 205, 143, 132, 31, 93, 179, 202, 132, 84, 3, 19, 40, 190, + 99, 120, 38, 42, 165, 159, 18, 153, 99, 212, 120, 4, 237, 237, 8, 57, + 69, 228, 186, 220, 183, 121, 139, 113, 179, 200, 21, 166, 75, 19, 149, 135, + 138, 170, 149, 14, 166, 110, 94, 129, 233, 66, 187, 163, 213, 96, 172, 4, + 145, 205, 41, 25, 97, 26, 66, 99, 104, 172, 227, 73, 193, 35, 142, 228, + 202, 85, 209, 10, 77, 47, 21, 8, 14, 215, 104, 211, 62, 186, 19, 226, + 180, 187, 81, 140, 101, 188, 252, 173, 1, 242, 9, 66, 177, 73, 5, 79, + 230, 53, 67, 28, 207, 98, 199, 52, 27, 66, 153, 200, 135, 247, 246, 210, + 128, 156, 173, 249, 92, 165, 93, 112, 247, 110, 0, 133, 56, 64, 199, 71, + 135, 104, 242, 50, 218, 28, 242, 216, 223, 229, 92, 19, 39, 36, 161, 233, + 104, 205, 56, 92, 20, 44, 81, 244, 215, 85, 116, 79, 44, 104, 236, 197, + 72, 17, 157, 105, 213, 76, 90, 85, 9, 54, 76, 248, 27, 39, 175, 107, + 79, 142, 31, 140, 48, 194, 73, 214, 79, 131, 65, 191, 175, 211, 154, 225, + 182, 226, 90, 169, 178, 95, 71, 89, 3, 4, 83, 27, 152, 218, 67, 67, + 225, 90, 159, 244, 215, 227, 41, 53, 214, 40, 178, 86, 46, 92, 27, 200, + 104, 126, 203, 185, 150, 90, 220, 210, 140, 33, 238, 113, 54, 31, 121, 4, + 49, 132, 62, 250, 9, 180, 120, 241, 248, 86, 67, 254, 57, 166, 141, 34, + 165, 218, 73, 167, 166, 85, 50, 191, 136, 177, 212, 175, 133, 8, 30, 106, + 201, 100, 208, 40, 119, 107, 182, 231, 27, 237, 58, 22, 225, 63, 21, 160, + 176, 7, 223, 124, 229, 53, 246, 170, 155, 70, 75, 68, 204, 221, 146, 48, + 109, 153, 25, 0, 157, 54, 208, 220, 240, 216, 113, 30, 230, 30, 46, 139, + 116, 215, 222, 10, 247, 103, 24, 86, 125, 8, 77, 202, 39, 152, 10, 225, + 131, 18, 117, 227, 249, 127, 160, 143, 86, 128, 207, 99, 207, 224, 42, 110, + 232, 36, 86, 179, 249, 138, 84, 121, 50, 5, 149, 93, 7, 200, 115, 209, + 110, 152, 124, 77, 52, 79, 221, 157, 195, 140, 54, 19, 60, 205, 158, 199, + 127, 207, 7, 117, 11, 227, 197, 72, 199, 187, 184, 43, 95, 0, 61, 143, + 176, 207, 65, 130, 87, 82, 140, 181, 182, 184, 223, 238, 244, 209, 170, 7, + 11, 100, 83, 5, 98, 125, 26, 188, 40, 137, 242, 22, 249, 227, 184, 80, + 44, 145, 32, 143, 254, 218, 115, 107, 76, 139, 212, 87, 253, 12, 11, 121, + 216, 159, 121, 87, 182, 101, 205, 151, 5, 0, 126, 150, 6, 166, 115, 36, + 14, 128, 159, 126, 200, 42, 189, 146, 192, 223, 186, 35, 71, 224, 63, 33, + 211, 207, 93, 66, 201, 31, 66, 220, 66, 97, 107, 95, 157, 213, 92, 81, + 217, 125, 242, 101, 243, 184, 255, 155, 2, 165, 9, 143, 103, 243, 133, 173, + 202, 202, 40, 221, 73, 177, 248, 57, 243, 125, 130, 127, 102, 47, 3, 227, + 27, 203, 33, 179, 249, 117, 28, 112, 157, 0, 210, 139, 43, 15, 192, 47, + 202, 45, 132, 10, 26, 163, 47, 220, 65, 169, 225, 235, 120, 57, 25, 176, + 206, 16, 38, 110, 84, 145, 28, 43, 63, 35, 144, 234, 249, 59, 22, 152, + 16, 175, 248, 2, 6, 109, 55, 92, 124, 77, 237, 166, 207, 82, 238, 140, + 22, 30, 214, 144, 177, 182, 229, 27, 180, 150, 186, 187, 231, 184, 242, 23, + 178, 119, 36, 24, 165, 82, 15, 195, 55, 147, 107, 45, 198, 133, 194, 95, + 20, 146, 8, 222, 235, 67, 80, 119, 234, 48, 223, 163, 51, 60, 217, 228, + 171, 195, 231, 250, 46, 111, 138, 143, 1, 48, 174, 116, 197, 186, 40, 61, + 177, 53, 65, 225, 171, 95, 186, 209, 199, 254, 152, 98, 179, 71, 140, 127, + 193, 177, 171, 61, 227, 117, 130, 92, 148, 43, 199, 156, 176, 219, 52, 218, + 133, 160, 123, 11, 221, 104, 254, 253, 144, 156, 245, 5, 156, 246, 226, 198, + 222, 172, 246, 13, 35, 210, 51, 99, 203, 213, 159, 248, 139, 71, 77, 120, + 75, 195, 89, 11, 122, 125, 43, 57, 30, 233, 45, 10, 87, 102, 171, 47, + 21, 167, 175, 143, 207, 121, 98, 48, 220, 247, 72, 184, 97, 83, 152, 72, + 51, 136, 17, 52, 249, 169, 8, 140, 219, 152, 5, 221, 132, 225, 17, 117, + 28, 72, 220, 69, 199, 108, 140, 175, 206, 165, 41, 39, 77, 194, 249, 154, + 121, 23, 85, 205, 128, 34, 118, 49, 220, 85, 5, 240, 181, 26, 210, 29, + 177, 24, 132, 91, 57, 218, 74, 217, 135, 225, 148, 82, 95, 98, 54, 127, + 58, 1, 85, 12, 122, 2, 58, 81, 16, 32, 168, 153, 186, 97, 214, 81, + 176, 244, 134, 168, 111, 127, 21, 251, 227, 215, 141, 191, 141, 90, 21, 177, + 142, 172, 29, 212, 128, 163, 54, 172, 20, 35, 174, 1, 225, 232, 74, 73, + 226, 154, 236, 45, 211, 64, 28, 142, 90, 175, 147, 230, 243, 66, 160, 207, + 186, 212, 201, 34, 58, 202, 236, 9, 218, 10, 226, 189, 74, 106, 75, 43, + 93, 1, 5, 162, 36, 42, 54, 86, 83, 35, 242, 114, 165, 93, 76, 8, + 94, 21, 110, 101, 241, 119, 219, 78, 115, 182, 5, 105, 116, 73, 50, 193, + 102, 254, 43, 197, 64, 236, 6, 105, 84, 206, 79, 127, 195, 151, 106, 76, + 122, 173, 234, 203, 34, 20, 204, 34, 195, 244, 209, 60, 32, 112, 157, 150, + 185, 49, 35, 11, 41, 230, 21, 63, 137, 1, 127, 147, 193, 77, 136, 174, + 109, 122, 243, 119, 160, 26, 5, 187, 191, 90, 83, 26, 214, 237, 162, 198, + 184, 179, 204, 246, 113, 43, 145, 228, 4, 250, 28, 187, 22, 149, 121, 67, + 94, 202, 229, 64, 35, 204, 174, 106, 180, 40, 224, 146, 117, 146, 217, 9, + 29, 22, 202, 177, 96, 25, 165, 0, 97, 146, 120, 15, 29, 230, 203, 30, + 181, 73, 37, 59, 38, 156, 8, 123, 215, 252, 229, 157, 240, 58, 91, 78, + 3, 189, 39, 232, 28, 175, 195, 69, 94, 127, 176, 218, 32, 40, 236, 113, + 175, 110, 241, 181, 238, 15, 46, 106, 58, 170, 48, 58, 254, 253, 190, 204, + 172, 214, 31, 202, 150, 134, 97, 230, 224, 255, 121, 206, 110, 102, 224, 49, + 94, 248, 23, 109, 243, 23, 208, 50, 120, 155, 166, 16, 193, 8, 111, 212, + 88, 114, 163, 247, 255, 144, 18, 87, 92, 47, 60, 250, 35, 102, 101, 150, + 228, 34, 28, 18, 59, 175, 136, 120, 186, 193, 15, 151, 143, 76, 54, 96, + 157, 183, 62, 4, 245, 231, 132, 94, 131, 139, 192, 253, 72, 194, 242, 7, + 202, 19, 20, 245, 122, 114, 177, 101, 133, 107, 109, 109, 112, 151, 71, 239, + 115, 43, 157, 185, 57, 149, 27, 82, 191, 118, 114, 80, 96, 115, 166, 79, + 166, 59, 23, 91, 223, 159, 217, 68, 63, 155, 173, 200, 73, 32, 199, 233, + 241, 206, 133, 125, 89, 87, 71, 172, 91, 56, 219, 233, 115, 26, 63, 53, + 98, 209, 57, 151, 243, 141, 54, 139, 107, 120, 252, 89, 249, 133, 67, 85, + 144, 135, 86, 238, 9, 133, 115, 95, 92, 97, 212, 81, 117, 70, 225, 199, + 123, 49, 84, 16, 84, 19, 134, 156, 33, 78, 195, 79, 191, 112, 44, 206, + 81, 249, 191, 4, 106, 159, 152, 246, 185, 246, 125, 7, 186, 106, 239, 25, + 144, 121, 78, 194, 199, 195, 218, 118, 189, 66, 2, 220, 105, 0, 77, 65, + 137, 55, 169, 82, 156, 126, 146, 139, 71, 44, 247, 210, 45, 171, 110, 252, + 221, 51, 80, 157, 164, 99, 10, 241, 175, 65, 32, 180, 254, 187, 89, 223, + 231, 227, 216, 197, 99, 217, 65, 187, 235, 152, 63, 74, 176, 36, 170, 236, + 134, 46, 98, 13, 108, 160, 126, 185, 245, 100, 96, 40, 240, 69, 171, 10, + 2, 141, 57, 105, 56, 82, 168, 46, 126, 161, 5, 219, 126, 1, 1, 165, + 92, 219, 81, 202, 86, 78, 174, 209, 195, 7, 142, 244, 119, 255, 115, 242, + 220, 11, 168, 135, 5, 71, 145, 137, 108, 10, 17, 30, 178, 142, 202, 147, + 24, 141, 161, 192, 79, 54, 62, 142, 239, 66, 209, 248, 101, 134, 83, 10, + 119, 121, 22, 240, 25, 227, 60, 180, 18, 46, 164, 105, 89, 30, 196, 167, + 206, 32, 32, 76, 54, 35, 10, 210, 170, 114, 127, 0, 216, 28, 71, 6, + 216, 15, 56, 201, 194, 246, 115, 182, 231, 202, 62, 218, 93, 252, 151, 125, + 48, 231, 133, 89, 67, 175, 88, 80, 25, 208, 80, 251, 226, 12, 4, 225, + 125, 37, 78, 202, 227, 212, 179, 219, 234, 223, 207, 188, 126, 214, 22, 59, + 134, 161, 108, 10, 115, 65, 40, 68, 211, 192, 129, 64, 163, 178, 183, 164, + 98, 212, 20, 146, 25, 16, 154, 29, 176, 107, 3, 15, 62, 226, 67, 119, + 189, 45, 123, 187, 83, 222, 206, 56, 135, 242, 121, 61, 220, 133, 171, 150, + 139, 221, 69, 112, 13, 183, 180, 76, 97, 122, 168, 79, 203, 136, 62, 161, + 138, 40, 253, 182, 3, 51, 229, 58, 195, 79, 191, 203, 248, 191, 180, 101, + 40, 189, 22, 127, 67, 139, 219, 213, 78, 11, 67, 215, 82, 41, 107, 54, + 143, 72, 223, 89, 246, 156, 91, 11, 157, 16, 225, 237, 213, 148, 187, 201, + 233, 101, 70, 211, 201, 113, 164, 185, 140, 169, 130, 42, 1, 222, 92, 59, + 66, 17, 108, 67, 197, 192, 251, 55, 203, 109, 189, 230, 131, 237, 215, 241, + 65, 148, 253, 241, 39, 141, 155, 148, 156, 244, 12, 68, 71, 109, 235, 241, + 4, 161, 177, 218, 114, 173, 113, 146, 11, 3, 219, 33, 141, 215, 62, 45, + 215, 184, 196, 97, 162, 250, 218, 110, 1, 190, 8, 67, 241, 94, 82, 196, + 64, 85, 118, 139, 240, 71, 67, 49, 241, 49, 129, 247, 44, 211, 46, 227, + 115, 140, 123, 192, 63, 82, 9, 155, 83, 167, 250, 70, 61, 66, 186, 217, + 46, 155, 128, 255, 232, 56, 224, 32, 254, 12, 204, 2, 85, 173, 20, 75, + 214, 73, 229, 18, 247, 145, 83, 241, 20, 245, 155, 15, 92, 111, 180, 101, + 179, 246, 5, 243, 112, 196, 44, 146, 16, 128, 155, 80, 106, 147, 110, 87, + 96, 17, 243, 247, 21, 87, 149, 78, 248, 20, 153, 249, 196, 11, 177, 96, + 227, 185, 136, 7, 244, 54, 177, 91, 192, 193, 111, 21, 159, 105, 143, 236, + 167, 215, 244, 121, 207, 245, 202, 161, 215, 45, 233, 32, 123, 220, 57, 34, + 171, 115, 37, 163, 75, 253, 140, 232, 51, 143, 204, 252, 146, 168, 85, 148, + 201, 161, 181, 231, 125, 44, 172, 79, 210, 12, 147, 82, 38, 254, 157, 225, + 167, 230, 182, 123, 63, 141, 146, 152, 136, 190, 80, 156, 163, 231, 33, 184, + 58, 200, 134, 28, 70, 202, 88, 195, 39, 224, 159, 154, 206, 183, 11, 96, + 102, 136, 26, 238, 179, 189, 226, 18, 30, 188, 148, 25, 3, 252, 154, 142, + 147, 145, 126, 11, 55, 1, 3, 108, 144, 55, 251, 167, 54, 127, 180, 216, + 77, 70, 138, 95, 166, 90, 48, 2, 211, 236, 235, 131, 107, 251, 91, 238, + 255, 0, 113, 41, 243, 14, 241, 252, 163, 99, 74, 25, 172, 87, 125, 36, + 203, 96, 189, 125, 222, 165, 138, 25, 76, 136, 67, 137, 161, 22, 232, 31, + 5, 96, 146, 214, 146, 21, 181, 198, 199, 34, 190, 63, 191, 201, 104, 116, + 123, 201, 64, 128, 84, 139, 86, 102, 244, 241, 162, 126, 4, 9, 132, 2, + 53, 113, 21, 1, 95, 7, 212, 123, 252, 100, 87, 78, 71, 28, 131, 135, + 183, 72, 196, 33, 66, 237, 12, 135, 58, 102, 69, 234, 214, 244, 57, 44, + 181, 120, 156, 218, 99, 146, 97, 15, 77, 113, 179, 142, 113, 226, 38, 72, + 128, 211, 160, 95, 52, 181, 30, 200, 64, 234, 8, 229, 150, 219, 225, 30, + 162, 223, 52, 242, 29, 31, 226, 91, 102, 235, 127, 213, 105, 123, 11, 172, + 190, 152, 59, 69, 1, 253, 126, 19, 145, 99, 33, 26, 198, 80, 74, 47, + 59, 77, 158, 60, 231, 51, 65, 145, 210, 232, 71, 100, 73, 71, 176, 239, + 42, 124, 176, 31, 254, 64, 223, 51, 195, 108, 165, 78, 202, 174, 212, 32, + 157, 58, 145, 133, 84, 230, 17, 206, 107, 72, 89, 129, 240, 179, 56, 231, + 218, 55, 236, 231, 122, 137, 50, 245, 171, 107, 223, 86, 17, 155, 68, 241, + 220, 120, 38, 95, 74, 110, 214, 202, 223, 60, 35, 120, 33, 79, 32, 58, + 77, 28, 121, 180, 99, 64, 201, 81, 156, 37, 28, 254, 219, 153, 74, 200, + 178, 70, 252, 140, 137, 127, 195, 238, 103, 228, 44, 96, 216, 12, 198, 246, + 206, 130, 67, 71, 129, 114, 145, 168, 64, 145, 128, 169, 169, 11, 28, 145, + 64, 144, 92, 206, 171, 135, 128, 121, 84, 142, 75, 37, 199, 208, 97, 243, + 114, 58, 152, 244, 201, 119, 76, 178, 3, 128, 185, 252, 146, 38, 165, 53, + 186, 175, 102, 81, 233, 115, 190, 227, 19, 31, 134, 132, 114, 24, 2, 21, + 249, 228, 128, 74, 119, 144, 74, 43, 168, 201, 131, 175, 254, 42, 103, 23, + 94, 138, 61, 40, 129, 252, 51, 80, 150, 135, 133, 55, 54, 122, 187, 93, + 42, 9, 154, 50, 93, 143, 241, 26, 80, 108, 7, 51, 144, 218, 129, 48, + 168, 66, 150, 108, 86, 127, 156, 232, 5, 54, 7, 182, 73, 210, 46, 115, + 84, 145, 113, 254, 195, 166, 106, 119, 116, 233, 154, 170, 185, 255, 99, 223, + 133, 115, 122, 10, 210, 76, 123, 92, 28, 159, 138, 133, 70, 126, 240, 215, + 36, 119, 180, 221, 156, 46, 89, 71, 1, 175, 247, 102, 107, 67, 136, 62, + 142, 197, 212, 50, 159, 107, 254, 44, 30, 59, 234, 51, 55, 35, 103, 170, + 231, 41, 111, 178, 14, 27, 77, 40, 43, 88, 199, 148, 211, 140, 17, 59, + 84, 182, 195, 92, 230, 109, 218, 165, 117, 39, 234, 195, 94, 70, 151, 202, + 167, 17, 179, 205, 213, 68, 102, 11, 120, 210, 150, 47, 150, 115, 186, 81, + 137, 53, 132, 36, 224, 107, 115, 100, 143, 118, 212, 239, 176, 139, 243, 36, + 235, 189, 48, 43, 25, 130, 143, 2, 165, 117, 173, 63, 189, 86, 180, 83, + 22, 204, 226, 141, 78, 199, 226, 195, 94, 183, 88, 103, 180, 205, 96, 254, + 235, 65, 144, 231, 11, 193, 111, 52, 129, 110, 125, 68, 42, 234, 138, 118, + 112, 69, 178, 191, 213, 115, 230, 221, 222, 97, 60, 187, 154, 161, 24, 25, + 147, 205, 69, 47, 45, 241, 84, 238, 249, 129, 6, 107, 126, 245, 187, 62, + 247, 159, 178, 6, 100, 80, 244, 229, 53, 83, 186, 208, 116, 164, 83, 217, + 76, 21, 191, 207, 44, 19, 21, 253, 153, 84, 92, 96, 41, 9, 10, 187, + 82, 155, 222, 146, 71, 130, 217, 44, 75, 51, 56, 119, 4, 77, 141, 46, + 0, 97, 157, 176, 42, 30, 102, 41, 39, 48, 191, 201, 226, 156, 80, 24, + 28, 109, 150, 215, 254, 211, 17, 87, 114, 111, 250, 7, 60, 233, 55, 121, + 139, 121, 167, 213, 0, 106, 85, 183, 122, 254, 65, 52, 95, 129, 197, 156, + 125, 235, 47, 46, 191, 44, 139, 244, 217, 239, 216, 228, 14, 234, 216, 19, + 13, 124, 221, 166, 60, 124, 187, 83, 242, 154, 57, 182, 125, 172, 123, 100, + 165, 156, 196, 254, 19, 73, 234, 83, 209, 242, 17, 54, 12, 115, 163, 148, + 32, 146, 41, 86, 171, 11, 77, 71, 162, 203, 42, 153, 71, 217, 254, 31, + 214, 184, 58, 41, 245, 132, 249, 54, 172, 163, 225, 203, 205, 52, 64, 105, + 110, 128, 162, 176, 118, 243, 173, 173, 69, 11, 98, 19, 183, 83, 247, 5, + 137, 91, 192, 122, 15, 151, 125, 192, 220, 207, 6, 118, 84, 8, 86, 196, + 88, 59, 246, 8, 250, 10, 27, 7, 233, 225, 220, 213, 222, 239, 138, 177, + 173, 63, 58, 16, 68, 113, 218, 216, 24, 25, 147, 176, 232, 249, 135, 194, + 5, 26, 37, 110, 251, 13, 178, 55, 28, 116, 84, 162, 145, 153, 117, 194, + 41, 16, 179, 64, 121, 52, 127, 232, 232, 53, 135, 212, 72, 122, 32, 112, + 152, 10, 241, 217, 107, 3, 99, 91, 115, 88, 107, 146, 120, 22, 156, 153, + 68, 104, 212, 39, 76, 144, 54, 58, 61, 91, 212, 96, 139, 35, 184, 37, + 17, 55, 223, 15, 75, 18, 55, 124, 232, 21, 10, 147, 24, 221, 23, 87, + 186, 27, 152, 51, 247, 112, 63, 56, 89, 180, 195, 67, 89, 105, 236, 102, + 235, 57, 17, 45, 151, 91, 186, 224, 171, 11, 149, 111, 102, 149, 50, 144, + 250, 243, 179, 20, 251, 203, 229, 228, 190, 33, 209, 254, 237, 112, 60, 222, + 179, 19, 224, 4, 78, 246, 239, 248, 80, 169, 180, 71, 190, 29, 178, 253, + 130, 207, 77, 202, 16, 108, 142, 201, 238, 135, 247, 155, 237, 187, 243, 139, + 247, 21, 141, 125, 213, 34, 106, 183, 4, 125, 40, 8, 104, 128, 73, 121, + 163, 122, 190, 121, 152, 45, 174, 52, 181, 139, 254, 242, 146, 36, 163, 183, + 147, 27, 234, 160, 222, 93, 232, 251, 153, 185, 158, 215, 9, 86, 49, 72, + 87, 154, 88, 169, 82, 186, 198, 240, 104, 92, 129, 217, 12, 124, 113, 206, + 117, 116, 149, 159, 149, 124, 219, 138, 96, 50, 177, 145, 244, 8, 232, 218, + 158, 22, 70, 31, 52, 226, 90, 7, 187, 135, 66, 35, 193, 62, 122, 72, + 201, 100, 66, 137, 236, 158, 187, 195, 107, 234, 27, 155, 187, 221, 131, 2, + 167, 165, 18, 225, 67, 72, 190, 63, 136, 69, 32, 185, 181, 234, 159, 57, + 4, 101, 127, 121, 3, 2, 235, 220, 44, 245, 160, 71, 64, 175, 55, 135, + 83, 250, 217, 239, 121, 81, 181, 160, 151, 70, 56, 101, 74, 169, 142, 167, + 10, 179, 233, 140, 156, 203, 110, 15, 95, 15, 8, 169, 164, 40, 43, 50, + 148, 216, 167, 161, 36, 142, 145, 126, 236, 167, 154, 120, 110, 239, 138, 53, + 152, 233, 115, 33, 203, 253, 249, 174, 176, 43, 0, 178, 120, 133, 211, 252, + 95, 221, 221, 185, 36, 145, 53, 15, 125, 26, 232, 42, 249, 86, 8, 205, + 183, 114, 81, 62, 187, 162, 4, 251, 26, 79, 159, 156, 42, 7, 83, 97, + 14, 124, 38, 252, 215, 34, 141, 252, 226, 61, 237, 252, 114, 117, 187, 21, + 53, 236, 151, 9, 147, 40, 68, 63, 10, 166, 84, 236, 0, 169, 196, 239, + 107, 214, 32, 53, 142, 172, 22, 245, 22, 154, 150, 105, 223, 5, 178, 48, + 151, 191, 251, 63, 50, 255, 54, 206, 221, 49, 249, 35, 133, 197, 248, 47, + 155, 185, 108, 172, 179, 104, 121, 72, 25, 83, 78, 205, 136, 136, 250, 47, + 68, 179, 166, 229, 237, 212, 214, 104, 191, 88, 159, 43, 30, 168, 89, 25, + 137, 79, 142, 7, 237, 19, 230, 87, 255, 20, 182, 27, 217, 197, 80, 45, + 119, 115, 241, 181, 96, 155, 160, 62, 57, 162, 103, 171, 196, 214, 243, 194, + 41, 223, 187, 22, 4, 157, 139, 4, 98, 193, 171, 27, 217, 8, 27, 100, + 222, 30, 235, 4, 127, 97, 243, 231, 102, 37, 47, 237, 58, 79, 189, 143, + 193, 144, 0, 150, 183, 0, 100, 29, 130, 166, 233, 150, 241, 61, 175, 23, + 56, 239, 24, 59, 143, 79, 27, 23, 124, 4, 9, 207, 73, 21, 181, 227, + 80, 149, 79, 226, 85, 110, 255, 126, 11, 66, 167, 203, 91, 50, 255, 189, + 91, 50, 79, 115, 160, 201, 112, 13, 25, 100, 68, 8, 218, 253, 185, 90, + 85, 79, 74, 27, 123, 23, 229, 57, 97, 91, 127, 106, 189, 186, 213, 74, + 233, 11, 137, 181, 51, 79, 108, 16, 145, 67, 82, 93, 245, 199, 182, 112, + 114, 208, 100, 151, 117, 222, 34, 187, 232, 137, 114, 251, 117, 217, 153, 37, + 215, 22, 113, 249, 198, 21, 184, 245, 107, 107, 27, 224, 2, 158, 165, 155, + 155, 104, 108, 215, 105, 154, 76, 171, 175, 245, 245, 206, 227, 85, 231, 208, + 127, 196, 191, 48, 150, 44, 38, 194, 191, 59, 10, 10, 175, 148, 162, 163, + 122, 167, 207, 145, 105, 234, 57, 199, 40, 112, 205, 98, 242, 238, 38, 68, + 192, 158, 91, 141, 80, 54, 12, 193, 215, 8, 201, 136, 185, 229, 109, 175, + 25, 245, 209, 147, 197, 233, 17, 80, 189, 150, 49, 218, 246, 78, 30, 112, + 64, 212, 109, 75, 232, 228, 171, 102, 239, 219, 152, 158, 217, 121, 43, 174, + 99, 82, 7, 113, 222, 107, 164, 30, 205, 236, 152, 19, 157, 60, 82, 165, + 34, 117, 23, 166, 185, 209, 212, 7, 250, 32, 167, 172, 234, 117, 139, 110, + 191, 14, 44, 158, 95, 115, 126, 115, 234, 209, 174, 95, 163, 117, 243, 203, + 182, 113, 182, 4, 33, 100, 143, 45, 225, 128, 69, 73, 183, 246, 91, 28, + 57, 20, 1, 175, 125, 128, 38, 4, 54, 93, 255, 28, 106, 122, 42, 104, + 35, 79, 242, 117, 75, 237, 149, 28, 178, 84, 224, 183, 116, 254, 120, 3, + 70, 154, 8, 57, 132, 86, 14, 119, 4, 130, 3, 155, 233, 177, 27, 28, + 233, 148, 205, 109, 29, 39, 33, 0, 160, 214, 129, 207, 180, 227, 131, 109, + 29, 136, 60, 47, 234, 99, 52, 57, 228, 87, 114, 138, 185, 19, 148, 152, + 114, 48, 12, 231, 182, 67, 228, 94, 253, 199, 34, 171, 238, 77, 59, 83, + 128, 137, 52, 74, 35, 236, 38, 181, 165, 106, 161, 12, 100, 76, 100, 237, + 69, 13, 211, 210, 117, 185, 178, 17, 231, 85, 134, 101, 66, 9, 71, 42, + 88, 125, 183, 106, 217, 38, 175, 131, 139, 75, 163, 134, 149, 70, 120, 146, + 156, 196, 151, 154, 242, 232, 163, 33, 206, 179, 123, 102, 249, 28, 11, 115, + 88, 20, 192, 244, 74, 33, 165, 176, 215, 142, 87, 229, 188, 139, 225, 192, + 111, 203, 55, 25, 241, 218, 22, 119, 121, 89, 69, 116, 214, 254, 94, 137, + 253, 168, 156, 155, 34, 150, 56, 126, 229, 79, 49, 150, 109, 99, 194, 179, + 40, 114, 63, 220, 161, 254, 73, 154, 211, 245, 21, 255, 63, 209, 45, 135, + 86, 234, 184, 213, 95, 28, 28, 244, 42, 66, 200, 83, 190, 81, 247, 24, + 153, 129, 180, 45, 159, 132, 4, 187, 171, 88, 178, 140, 143, 60, 212, 187, + 102, 125, 212, 66, 85, 133, 248, 58, 240, 126, 196, 7, 68, 71, 137, 202, + 116, 79, 137, 229, 156, 122, 69, 94, 146, 226, 198, 191, 116, 96, 33, 50, + 189, 32, 4, 5, 92, 116, 29, 122, 137, 140, 42, 199, 138, 59, 38, 48, + 178, 115, 216, 201, 225, 170, 183, 55, 248, 151, 58, 187, 184, 152, 106, 130, + 176, 52, 36, 73, 99, 77, 12, 166, 238, 52, 231, 86, 144, 91, 2, 248, + 246, 127, 5, 182, 201, 149, 205, 246, 73, 158, 98, 4, 20, 138, 51, 176, + 71, 169, 209, 237, 230, 100, 244, 243, 107, 80, 113, 246, 233, 115, 26, 175, + 72, 11, 38, 165, 68, 108, 163, 27, 38, 43, 246, 18, 153, 208, 118, 235, + 201, 225, 235, 17, 65, 53, 173, 72, 230, 232, 105, 215, 41, 180, 191, 61, + 31, 28, 214, 219, 29, 209, 90, 206, 232, 80, 22, 101, 237, 61, 105, 128, + 249, 224, 23, 242, 8, 250, 190, 130, 207, 148, 102, 166, 241, 67, 58, 8, + 61, 43, 58, 21, 148, 188, 40, 139, 116, 11, 79, 186, 85, 9, 240, 164, + 117, 238, 157, 59, 244, 184, 250, 69, 143, 88, 147, 126, 237, 37, 6, 159, + 130, 18, 72, 138, 251, 58, 136, 155, 92, 42, 173, 253, 171, 166, 57, 160, + 162, 211, 173, 241, 66, 121, 37, 176, 180, 140, 117, 240, 132, 181, 16, 234, + 173, 59, 98, 9, 123, 31, 18, 165, 45, 182, 89, 112, 130, 79, 53, 10, + 120, 252, 52, 114, 58, 57, 146, 87, 222, 154, 231, 215, 219, 84, 246, 85, + 57, 206, 180, 66, 125, 212, 226, 45, 212, 74, 132, 27, 185, 34, 150, 235, + 119, 218, 77, 70, 235, 171, 112, 123, 174, 87, 160, 89, 86, 219, 3, 47, + 39, 240, 116, 102, 70, 107, 31, 55, 102, 167, 4, 101, 119, 146, 176, 237, + 168, 123, 84, 118, 218, 112, 118, 52, 18, 56, 120, 216, 66, 187, 31, 12, + 205, 53, 119, 26, 225, 215, 195, 226, 2, 201, 75, 105, 65, 81, 45, 239, + 114, 182, 155, 135, 95, 153, 240, 143, 109, 109, 219, 218, 224, 26, 175, 35, + 86, 128, 209, 255, 71, 26, 86, 115, 22, 70, 167, 3, 105, 128, 160, 142, + 163, 149, 168, 112, 8, 12, 14, 119, 65, 43, 183, 105, 197, 156, 207, 226, + 231, 239, 48, 62, 4, 49, 169, 234, 123, 26, 164, 98, 119, 33, 170, 43, + 39, 6, 128, 15, 217, 209, 229, 109, 240, 180, 150, 169, 252, 118, 242, 240, + 108, 204, 24, 107, 199, 108, 184, 110, 208, 52, 175, 245, 241, 123, 90, 123, + 150, 211, 56, 75, 247, 140, 187, 53, 172, 174, 90, 223, 117, 128, 254, 97, + 235, 170, 193, 190, 34, 215, 109, 18, 109, 13, 118, 134, 45, 22, 100, 73, + 141, 199, 203, 124, 169, 191, 102, 108, 250, 201, 188, 39, 236, 74, 154, 159, + 170, 137, 69, 63, 82, 44, 177, 240, 178, 157, 53, 89, 6, 99, 5, 13, + 134, 169, 195, 121, 229, 179, 212, 123, 198, 131, 96, 250, 187, 94, 106, 51, + 219, 16, 147, 227, 108, 124, 240, 237, 172, 43, 83, 157, 124, 246, 118, 249, + 175, 43, 235, 221, 18, 24, 166, 127, 255, 210, 199, 57, 134, 73, 141, 254, + 219, 209, 19, 217, 36, 25, 104, 225, 133, 24, 3, 130, 62, 103, 148, 212, + 243, 122, 52, 213, 102, 26, 144, 227, 189, 143, 151, 230, 98, 87, 214, 147, + 110, 31, 43, 248, 142, 126, 199, 95, 170, 186, 67, 225, 208, 49, 50, 159, + 108, 174, 152, 118, 43, 193, 187, 13, 63, 141, 94, 118, 113, 200, 75, 165, + 117, 247, 53, 209, 151, 163, 241, 24, 23, 252, 149, 18, 16, 77, 69, 208, + 219, 254, 159, 220, 62, 99, 26, 31, 231, 88, 150, 219, 168, 151, 178, 181, + 234, 141, 124, 130, 37, 1, 21, 195, 96, 139, 179, 136, 145, 29, 159, 213, + 248, 10, 174, 213, 22, 180, 250, 251, 30, 42, 228, 139, 178, 90, 19, 228, + 100, 120, 205, 54, 6, 189, 213, 203, 193, 43, 218, 211, 27, 93, 76, 181, + 127, 159, 43, 96, 233, 249, 118, 252, 127, 59, 67, 82, 65, 48, 100, 170, + 227, 197, 141, 49, 153, 31, 189, 176, 102, 14, 101, 152, 242, 25, 251, 47, + 242, 67, 114, 61, 184, 29, 60, 163, 186, 19, 17, 36, 42, 76, 31, 246, + 195, 224, 206, 221, 89, 69, 218, 112, 148, 98, 60, 154, 28, 199, 206, 59, + 157, 199, 18, 214, 53, 217, 211, 254, 128, 220, 189, 96, 134, 57, 73, 152, + 41, 52, 0, 93, 23, 215, 124, 209, 63, 252, 134, 64, 224, 183, 197, 94, + 46, 214, 214, 233, 202, 211, 155, 236, 31, 238, 220, 132, 54, 88, 122, 140, + 146, 11, 88, 164, 238, 156, 72, 239, 225, 82, 157, 144, 27, 240, 5, 231, + 89, 25, 63, 50, 227, 219, 3, 5, 218, 125, 13, 151, 59, 40, 162, 211, + 79, 33, 157, 76, 245, 55, 229, 140, 88, 50, 221, 42, 52, 162, 106, 212, + 125, 187, 254, 0, 126, 156, 98, 149, 35, 94, 247, 215, 131, 86, 116, 176, + 3, 56, 30, 26, 138, 113, 71, 255, 77, 143, 52, 111, 20, 113, 47, 88, + 104, 110, 225, 164, 226, 8, 74, 180, 182, 183, 206, 215, 84, 12, 46, 61, + 177, 168, 102, 244, 93, 199, 243, 247, 214, 227, 131, 185, 103, 131, 49, 3, + 49, 18, 74, 111, 249, 150, 2, 113, 165, 221, 7, 93, 110, 59, 242, 246, + 243, 168, 45, 182, 45, 140, 19, 41, 72, 10, 164, 190, 17, 174, 216, 36, + 216, 3, 1, 198, 230, 150, 19, 0, 114, 10, 75, 166, 138, 161, 0, 113, + 132, 128, 116, 201, 147, 42, 63, 211, 56, 195, 45, 125, 69, 55, 177, 149, + 228, 7, 78, 217, 133, 35, 108, 182, 210, 185, 124, 187, 167, 95, 246, 202, + 121, 167, 61, 61, 239, 37, 153, 143, 109, 126, 42, 69, 174, 253, 132, 161, + 118, 14, 10, 7, 141, 92, 188, 60, 81, 174, 93, 28, 58, 223, 217, 119, + 84, 213, 230, 132, 248, 31, 47, 141, 88, 249, 28, 205, 19, 5, 183, 167, + 88, 177, 66, 242, 50, 66, 255, 31, 218, 182, 209, 12, 246, 151, 87, 252, + 211, 231, 32, 120, 95, 76, 180, 20, 124, 238, 190, 60, 165, 239, 207, 37, + 221, 115, 145, 126, 61, 51, 141, 54, 64, 219, 247, 164, 74, 19, 7, 93, + 27, 150, 115, 224, 228, 172, 232, 113, 6, 148, 40, 229, 228, 32, 17, 92, + 215, 75, 64, 50, 235, 127, 109, 127, 152, 99, 73, 55, 210, 245, 55, 37, + 236, 244, 136, 154, 177, 231, 119, 30, 187, 225, 83, 240, 237, 183, 80, 245, + 10, 129, 181, 156, 137, 27, 79, 97, 145, 78, 100, 127, 79, 224, 218, 244, + 49, 70, 225, 131, 138, 102, 32, 110, 123, 110, 49, 161, 246, 27, 99, 115, + 171, 159, 45, 44, 15, 108, 51, 173, 24, 4, 170, 76, 255, 41, 27, 0, + 27, 35, 61, 145, 246, 241, 138, 152, 47, 51, 2, 153, 171, 79, 81, 176, + 123, 63, 192, 74, 27, 243, 22, 51, 86, 243, 48, 24, 129, 162, 69, 218, + 102, 143, 135, 107, 52, 182, 189, 25, 142, 206, 227, 144, 140, 57, 124, 252, + 97, 157, 61, 55, 43, 76, 52, 197, 146, 154, 83, 0, 150, 16, 85, 76, + 230, 32, 23, 86, 31, 241, 251, 88, 183, 195, 242, 192, 181, 160, 229, 185, + 229, 186, 72, 219, 249, 142, 111, 178, 42, 163, 117, 93, 31, 171, 161, 227, + 194, 51, 36, 53, 116, 0, 233, 37, 150, 128, 144, 8, 168, 198, 68, 35, + 57, 148, 64, 207, 148, 64, 213, 174, 223, 174, 129, 171, 81, 132, 1, 90, + 208, 100, 105, 209, 10, 209, 228, 138, 169, 82, 197, 37, 172, 32, 222, 70, + 180, 78, 59, 234, 106, 250, 76, 237, 59, 173, 178, 212, 151, 107, 131, 245, + 14, 218, 71, 56, 187, 138, 74, 101, 15, 32, 18, 131, 21, 57, 6, 32, + 115, 75, 244, 119, 168, 158, 154, 147, 72, 143, 232, 51, 49, 181, 115, 27, + 96, 141, 93, 202, 36, 38, 23, 61, 150, 171, 239, 66, 13, 183, 126, 24, + 99, 175, 110, 189, 88, 170, 252, 139, 127, 179, 106, 243, 140, 208, 243, 110, + 145, 64, 161, 4, 191, 209, 211, 72, 135, 24, 121, 210, 109, 42, 134, 9, + 160, 241, 186, 161, 203, 85, 212, 3, 23, 228, 75, 147, 133, 9, 100, 65, + 195, 165, 252, 229, 177, 199, 170, 63, 194, 247, 76, 171, 66, 203, 193, 3, + 74, 91, 86, 31, 85, 185, 52, 27, 175, 175, 84, 137, 51, 233, 26, 52, + 16, 75, 185, 95, 35, 167, 251, 67, 83, 217, 9, 241, 43, 252, 76, 242, + 101, 115, 133, 173, 154, 251, 33, 116, 118, 243, 152, 63, 173, 153, 63, 75, + 90, 106, 203, 197, 141, 149, 127, 9, 133, 218, 223, 193, 62, 19, 48, 231, + 45, 146, 21, 164, 1, 42, 43, 187, 75, 88, 20, 39, 233, 165, 20, 76, + 26, 145, 226, 155, 106, 187, 26, 195, 23, 212, 49, 60, 145, 149, 37, 167, + 73, 106, 203, 228, 185, 223, 108, 12, 187, 239, 88, 126, 27, 154, 235, 203, + 207, 187, 1, 114, 12, 112, 238, 17, 185, 120, 227, 177, 242, 191, 10, 18, + 241, 143, 21, 239, 31, 150, 102, 60, 15, 167, 209, 64, 117, 237, 45, 45, + 217, 147, 32, 28, 98, 221, 12, 20, 2, 176, 213, 147, 95, 31, 176, 64, + 237, 55, 53, 44, 105, 249, 43, 111, 73, 162, 180, 4, 62, 66, 118, 36, + 215, 254, 183, 249, 170, 39, 21, 69, 147, 65, 105, 136, 232, 160, 174, 141, + 84, 222, 189, 33, 250, 197, 226, 170, 246, 127, 87, 25, 10, 181, 46, 151, + 216, 250, 227, 131, 115, 64, 217, 11, 190, 199, 122, 148, 242, 221, 46, 169, + 45, 54, 9, 90, 251, 94, 61, 211, 30, 67, 199, 115, 204, 4, 199, 203, + 109, 137, 60, 223, 206, 3, 144, 170, 215, 224, 72, 247, 128, 64, 147, 140, + 223, 125, 20, 67, 248, 253, 206, 5, 44, 72, 160, 33, 20, 166, 80, 123, + 194, 220, 16, 134, 206, 24, 66, 217, 177, 231, 223, 66, 251, 253, 235, 180, + 36, 205, 107, 173, 198, 108, 83, 120, 82, 128, 120, 245, 67, 23, 248, 203, + 28, 14, 75, 235, 117, 111, 34, 127, 39, 52, 169, 101, 28, 144, 123, 20, + 197, 116, 96, 141, 201, 246, 61, 101, 132, 127, 98, 178, 186, 139, 226, 132, + 55, 229, 116, 75, 43, 241, 119, 139, 104, 169, 215, 199, 226, 113, 178, 214, + 153, 159, 139, 208, 106, 136, 77, 149, 72, 248, 49, 179, 98, 110, 192, 105, + 128, 27, 245, 36, 215, 210, 187, 98, 45, 92, 51, 238, 57, 153, 113, 21, + 86, 147, 122, 138, 3, 70, 66, 84, 135, 96, 199, 23, 123, 105, 226, 81, + 171, 23, 228, 73, 234, 240, 50, 135, 108, 143, 140, 247, 26, 245, 43, 94, + 183, 180, 240, 235, 159, 127, 57, 119, 6, 34, 58, 112, 170, 62, 37, 57, + 171, 56, 223, 147, 98, 204, 183, 146, 154, 85, 172, 49, 76, 84, 231, 138, + 117, 46, 81, 57, 240, 43, 102, 130, 234, 208, 237, 88, 164, 124, 128, 104, + 167, 38, 88, 73, 7, 131, 234, 67, 4, 213, 8, 211, 84, 81, 197, 133, + 123, 247, 254, 101, 230, 68, 245, 220, 193, 152, 208, 91, 63, 109, 228, 184, + 117, 28, 114, 146, 98, 142, 195, 4, 139, 48, 186, 242, 211, 124, 175, 224, + 69, 38, 35, 14, 253, 245, 242, 184, 138, 4, 206, 221, 15, 125, 189, 97, + 127, 46, 212, 10, 55, 1, 69, 56, 31, 180, 245, 93, 175, 58, 220, 3, + 164, 88, 22, 74, 157, 113, 246, 189, 65, 97, 235, 189, 126, 106, 50, 120, + 180, 71, 120, 11, 200, 48, 19, 57, 236, 64, 234, 180, 243, 32, 228, 127, + 228, 253, 42, 20, 238, 109, 161, 67, 73, 52, 35, 126, 197, 5, 117, 12, + 86, 215, 168, 60, 159, 4, 74, 193, 92, 104, 190, 30, 185, 187, 153, 208, + 87, 245, 62, 200, 16, 204, 189, 141, 188, 226, 187, 144, 101, 51, 86, 204, + 26, 22, 246, 230, 176, 81, 195, 19, 126, 58, 91, 30, 204, 178, 248, 217, + 81, 155, 68, 145, 42, 9, 22, 68, 22, 107, 25, 86, 153, 225, 224, 143, + 128, 94, 164, 65, 168, 173, 178, 181, 97, 100, 159, 212, 164, 213, 75, 25, + 35, 225, 133, 5, 243, 65, 39, 158, 155, 153, 3, 81, 53, 165, 153, 52, + 237, 226, 122, 245, 248, 255, 60, 13, 2, 41, 202, 232, 184, 57, 152, 133, + 105, 159, 33, 220, 49, 135, 76, 198, 212, 70, 168, 43, 233, 168, 180, 88, + 139, 246, 219, 120, 12, 161, 238, 88, 228, 9, 77, 236, 129, 227, 73, 91, + 104, 222, 104, 205, 28, 140, 205, 167, 178, 222, 150, 197, 139, 205, 66, 245, + 48, 241, 80, 225, 218, 27, 159, 205, 64, 148, 107, 54, 46, 190, 61, 0, + 161, 228, 124, 123, 18, 170, 35, 46, 53, 61, 171, 154, 121, 253, 187, 158, + 102, 194, 132, 94, 49, 239, 86, 57, 205, 129, 185, 234, 50, 56, 219, 36, + 56, 77, 247, 160, 75, 239, 154, 122, 34, 34, 143, 66, 53, 20, 212, 246, + 3, 79, 229, 119, 50, 132, 221, 187, 208, 82, 149, 183, 151, 200, 181, 97, + 12, 4, 136, 233, 171, 247, 128, 211, 234, 122, 152, 140, 221, 82, 83, 98, + 185, 95, 122, 23, 120, 124, 112, 240, 39, 16, 49, 140, 225, 135, 88, 69, + 96, 125, 246, 99, 224, 165, 148, 178, 35, 63, 192, 217, 39, 153, 63, 32, + 109, 142, 224, 12, 132, 10, 55, 49, 140, 217, 141, 113, 10, 72, 92, 37, + 121, 96, 72, 35, 184, 70, 156, 225, 140, 110, 150, 24, 95, 209, 172, 140, + 187, 10, 154, 58, 113, 215, 254, 36, 101, 155, 5, 46, 249, 59, 238, 164, + 25, 212, 35, 5, 87, 45, 183, 124, 174, 6, 182, 241, 206, 128, 118, 190, + 239, 160, 140, 2, 149, 90, 185, 125, 192, 8, 75, 105, 184, 51, 2, 11, + 198, 85, 249, 100, 88, 73, 229, 189, 80, 81, 244, 167, 62, 110, 52, 13, + 254, 122, 144, 170, 206, 64, 239, 191, 0, 73, 235, 143, 120, 81, 33, 87, + 83, 154, 156, 163, 31, 172, 104, 196, 78, 144, 100, 3, 54, 202, 67, 177, + 217, 80, 207, 235, 48, 12, 127, 78, 116, 96, 238, 226, 97, 154, 97, 120, + 19, 33, 89, 14, 160, 149, 243, 246, 196, 219, 74, 113, 225, 92, 32, 216, + 10, 50, 176, 127, 113, 63, 157, 143, 190, 245, 94, 244, 103, 85, 143, 162, + 61, 177, 203, 240, 204, 55, 183, 226, 251, 205, 53, 25, 19, 197, 160, 34, + 42, 128, 169, 80, 11, 210, 133, 105, 128, 175, 107, 72, 222, 130, 95, 209, + 93, 161, 16, 35, 244, 178, 236, 100, 20, 129, 190, 118, 246, 108, 68, 206, + 105, 58, 91, 90, 149, 0, 168, 95, 115, 63, 54, 240, 7, 164, 186, 100, + 76, 81, 225, 58, 178, 14, 46, 79, 31, 226, 180, 34, 164, 191, 84, 22, + 244, 90, 105, 13, 83, 133, 230, 81, 45, 49, 157, 84, 22, 168, 167, 205, + 219, 123, 209, 80, 87, 205, 180, 152, 162, 225, 229, 142, 72, 250, 240, 134, + 185, 145, 112, 149, 25, 185, 198, 174, 213, 83, 145, 151, 228, 138, 96, 152, + 242, 251, 227, 53, 229, 136, 37, 147, 184, 141, 104, 221, 51, 219, 21, 93, + 42, 253, 183, 57, 203, 92, 7, 240, 82, 171, 103, 167, 115, 233, 175, 142, + 8, 112, 10, 56, 44, 192, 231, 79, 18, 8, 68, 128, 106, 121, 225, 149, + 30, 210, 173, 86, 240, 30, 138, 197, 89, 213, 63, 161, 106, 65, 141, 57, + 96, 102, 191, 28, 56, 9, 201, 3, 248, 113, 118, 51, 121, 247, 83, 135, + 51, 54, 14, 19, 49, 175, 59, 206, 112, 172, 155, 243, 75, 19, 154, 102, + 188, 11, 76, 198, 136, 11, 44, 154, 139, 48, 34, 194, 116, 170, 198, 127, + 132, 231, 200, 44, 61, 210, 93, 20, 159, 201, 183, 39, 78, 178, 225, 112, + 50, 254, 198, 200, 207, 18, 196, 209, 222, 252, 67, 56, 186, 71, 24, 210, + 30, 105, 32, 102, 99, 239, 195, 191, 131, 246, 65, 121, 91, 66, 112, 28, + 170, 67, 28, 144, 187, 46, 117, 97, 187, 240, 250, 118, 249, 68, 151, 248, + 219, 208, 103, 242, 166, 122, 220, 59, 50, 215, 90, 160, 15, 15, 96, 89, + 167, 87, 22, 253, 137, 202, 126, 145, 162, 171, 97, 181, 102, 50, 107, 230, + 31, 183, 133, 105, 23, 233, 228, 13, 247, 169, 79, 53, 76, 138, 29, 51, + 53, 221, 126, 199, 47, 153, 184, 183, 198, 109, 192, 203, 178, 26, 115, 177, + 118, 158, 181, 43, 48, 174, 195, 253, 43, 18, 172, 171, 101, 129, 255, 63, + 41, 49, 160, 15, 86, 108, 235, 87, 115, 36, 93, 46, 164, 152, 49, 31, + 137, 125, 174, 115, 196, 240, 117, 226, 183, 151, 73, 30, 75, 59, 61, 160, + 96, 157, 215, 246, 160, 136, 82, 95, 181, 13, 207, 158, 106, 81, 18, 27, + 182, 35, 249, 72, 148, 128, 15, 82, 68, 197, 0, 159, 149, 239, 34, 250, + 171, 70, 200, 219, 214, 18, 134, 14, 71, 69, 219, 145, 208, 125, 65, 232, + 201, 212, 148, 39, 208, 142, 54, 38, 32, 154, 124, 35, 76, 173, 240, 232, + 23, 74, 183, 118, 137, 244, 180, 149, 195, 198, 105, 25, 246, 236, 155, 88, + 230, 134, 32, 126, 183, 72, 127, 129, 139, 161, 224, 222, 127, 107, 201, 78, + 227, 207, 10, 48, 9, 199, 240, 176, 49, 165, 95, 200, 101, 89, 40, 229, + 28, 8, 41, 193, 173, 218, 63, 229, 216, 170, 82, 90, 162, 243, 0, 125, + 248, 79, 186, 228, 44, 197, 178, 58, 196, 251, 85, 19, 254, 130, 110, 78, + 91, 217, 146, 16, 90, 221, 6, 129, 173, 73, 56, 77, 72, 19, 8, 14, + 129, 84, 19, 88, 146, 252, 137, 165, 222, 7, 199, 107, 135, 13, 253, 137, + 180, 184, 240, 37, 238, 133, 135, 80, 170, 172, 60, 80, 94, 130, 246, 166, + 63, 181, 30, 103, 97, 138, 193, 148, 96, 82, 61, 47, 188, 230, 118, 65, + 74, 28, 123, 50, 73, 12, 187, 123, 129, 19, 95, 213, 61, 153, 85, 243, + 44, 195, 249, 250, 121, 175, 42, 187, 154, 233, 91, 217, 49, 130, 129, 172, + 250, 182, 203, 30, 93, 213, 217, 24, 28, 198, 4, 208, 61, 207, 108, 120, + 22, 39, 136, 252, 123, 15, 188, 34, 35, 177, 35, 134, 178, 221, 217, 22, + 51, 18, 22, 215, 47, 68, 120, 130, 0, 192, 242, 170, 170, 202, 220, 179, + 185, 81, 204, 10, 115, 181, 231, 246, 172, 38, 43, 145, 56, 171, 219, 34, + 17, 96, 165, 209, 53, 44, 68, 74, 236, 249, 192, 35, 204, 123, 56, 118, + 174, 172, 151, 249, 36, 21, 133, 119, 237, 232, 61, 125, 6, 124, 200, 62, + 68, 67, 40, 196, 202, 84, 213, 160, 237, 85, 249, 125, 41, 187, 126, 48, + 152, 124, 104, 211, 127, 96, 167, 184, 23, 161, 68, 106, 119, 224, 226, 148, + 234, 54, 155, 168, 186, 193, 167, 15, 242, 100, 82, 15, 205, 247, 34, 24, + 134, 152, 115, 132, 114, 196, 0, 136, 242, 73, 91, 35, 90, 4, 161, 138, + 163, 21, 16, 244, 60, 158, 199, 246, 233, 150, 10, 142, 248, 196, 224, 129, + 8, 158, 81, 11, 92, 96, 197, 23, 45, 104, 235, 250, 9, 31, 47, 153, + 116, 22, 170, 186, 150, 46, 214, 246, 75, 116, 4, 242, 147, 168, 177, 134, + 143, 149, 36, 139, 224, 127, 143, 167, 208, 115, 158, 250, 132, 4, 124, 204, + 99, 217, 239, 97, 5, 38, 50, 17, 176, 171, 96, 92, 88, 219, 195, 184, + 160, 158, 175, 10, 175, 33, 245, 28, 55, 56, 207, 47, 46, 114, 108, 196, + 101, 93, 39, 227, 183, 40, 40, 109, 121, 123, 90, 85, 162, 165, 227, 200, + 238, 136, 223, 36, 77, 179, 45, 156, 51, 95, 33, 15, 219, 71, 37, 98, + 141, 150, 179, 78, 217, 221, 130, 186, 155, 84, 146, 217, 210, 202, 91, 212, + 50, 129, 188, 203, 28, 213, 10, 230, 40, 47, 215, 77, 161, 88, 71, 56, + 82, 124, 130, 249, 70, 139, 142, 23, 78, 139, 252, 32, 223, 90, 214, 27, + 94, 23, 12, 240, 77, 145, 71, 172, 75, 235, 141, 83, 145, 50, 101, 166, + 87, 154, 179, 203, 27, 233, 169, 45, 28, 41, 211, 46, 144, 123, 62, 62, + 205, 178, 180, 89, 32, 194, 238, 151, 217, 164, 214, 241, 164, 96, 215, 46, + 141, 189, 86, 97, 143, 4, 227, 73, 20, 221, 238, 66, 3, 132, 135, 229, + 22, 60, 152, 102, 211, 20, 250, 225, 36, 212, 131, 182, 212, 216, 84, 141, + 133, 86, 163, 136, 107, 219, 8, 100, 189, 138, 217, 60, 131, 237, 64, 37, + 241, 85, 140, 47, 54, 75, 58, 76, 66, 104, 245, 201, 199, 236, 188, 71, + 30, 171, 233, 190, 81, 120, 166, 63, 237, 249, 233, 192, 5, 24, 231, 193, + 39, 99, 101, 108, 92, 109, 156, 211, 111, 87, 157, 130, 16, 58, 113, 47, + 101, 152, 60, 183, 37, 227, 52, 255, 213, 16, 112, 234, 223, 197, 101, 73, + 120, 94, 60, 158, 82, 227, 131, 13, 4, 167, 78, 126, 120, 154, 26, 246, + 35, 145, 40, 150, 7, 208, 243, 100, 68, 89, 200, 139, 138, 121, 37, 28, + 35, 197, 227, 79, 19, 130, 171, 91, 116, 57, 153, 140, 217, 236, 7, 180, + 221, 226, 163, 199, 158, 131, 200, 37, 48, 41, 157, 175, 139, 71, 53, 172, + 113, 159, 133, 47, 139, 113, 157, 40, 88, 44, 115, 105, 104, 219, 211, 18, + 164, 170, 127, 5, 178, 115, 181, 143, 30, 173, 6, 186, 183, 45, 56, 94, + 252, 210, 171, 154, 10, 17, 34, 153, 4, 11, 176, 85, 144, 114, 36, 247, + 34, 67, 187, 69, 164, 168, 120, 82, 186, 46, 15, 147, 105, 48, 76, 235, + 15, 218, 86, 160, 19, 220, 119, 241, 103, 252, 196, 58, 74, 131, 214, 109, + 17, 175, 75, 203, 167, 17, 60, 52, 251, 130, 55, 184, 165, 83, 225, 231, + 184, 208, 196, 88, 70, 8, 3, 43, 78, 107, 158, 180, 130, 248, 194, 16, + 46, 54, 100, 98, 121, 67, 185, 17, 181, 210, 5, 15, 178, 196, 80, 220, + 28, 103, 220, 231, 167, 10, 122, 225, 194, 118, 157, 192, 195, 205, 130, 253, + 94, 246, 177, 74, 149, 90, 120, 188, 230, 48, 77, 168, 50, 76, 130, 136, + 200, 219, 209, 192, 20, 10, 193, 97, 205, 136, 98, 117, 128, 170, 198, 220, + 218, 180, 178, 186, 150, 227, 196, 161, 4, 244, 124, 31, 85, 243, 34, 78, + 187, 226, 164, 167, 122, 56, 114, 232, 140, 189, 160, 19, 184, 223, 165, 202, + 86, 210, 102, 183, 50, 30, 109, 134, 23, 102, 171, 130, 93, 106, 2, 117, + 80, 82, 197, 193, 247, 137, 255, 255, 127, 38, 13, 82, 103, 51, 179, 220, + 133, 247, 104, 152, 160, 229, 160, 214, 152, 157, 87, 183, 82, 43, 36, 19, + 80, 192, 122, 186, 201, 116, 190, 220, 131, 228, 153, 197, 212, 112, 233, 124, + 114, 212, 106, 195, 129, 141, 204, 238, 98, 247, 90, 244, 23, 118, 2, 168, + 71, 48, 223, 253, 187, 16, 204, 230, 46, 221, 30, 243, 27, 129, 155, 210, + 159, 84, 56, 212, 197, 131, 174, 59, 85, 108, 80, 36, 31, 210, 71, 228, + 254, 171, 67, 129, 154, 175, 245, 140, 11, 167, 43, 69, 231, 227, 91, 183, + 133, 108, 4, 151, 128, 64, 243, 215, 74, 160, 186, 217, 38, 28, 186, 75, + 178, 151, 214, 5, 49, 158, 242, 126, 91, 249, 88, 156, 110, 124, 205, 125, + 227, 19, 235, 172, 103, 200, 190, 121, 169, 140, 118, 156, 21, 152, 34, 31, + 235, 46, 191, 107, 37, 109, 135, 112, 195, 9, 245, 43, 96, 232, 74, 8, + 193, 131, 70, 140, 180, 204, 219, 243, 72, 70, 16, 11, 227, 0, 27, 252, + 142, 183, 199, 103, 114, 149, 221, 235, 69, 92, 245, 9, 227, 43, 173, 139, + 119, 85, 104, 214, 84, 126, 244, 243, 122, 14, 164, 185, 104, 176, 55, 133, + 44, 28, 208, 232, 50, 71, 32, 78, 200, 95, 153, 70, 82, 243, 91, 164, + 64, 159, 173, 244, 103, 78, 29, 218, 209, 124, 118, 153, 42, 69, 240, 237, + 228, 33, 155, 17, 61, 27, 233, 171, 6, 240, 48, 113, 243, 134, 207, 120, + 216, 61, 188, 247, 231, 185, 163, 43, 140, 138, 235, 132, 219, 47, 38, 93, + 205, 6, 247, 195, 200, 79, 87, 111, 210, 54, 222, 179, 108, 163, 253, 22, + 22, 101, 180, 6, 61, 41, 91, 95, 237, 186, 166, 110, 225, 139, 205, 146, + 41, 133, 153, 114, 63, 48, 110, 208, 168, 38, 233, 141, 23, 136, 236, 22, + 220, 14, 62, 224, 46, 20, 193, 181, 107, 14, 234, 156, 234, 108, 30, 112, + 235, 126, 237, 189, 252, 240, 240, 3, 175, 210, 85, 35, 230, 115, 219, 184, + 173, 48, 84, 250, 52, 113, 44, 187, 173, 253, 153, 177, 32, 127, 98, 100, + 180, 211, 71, 146, 82, 1, 69, 200, 165, 198, 121, 133, 232, 0, 237, 157, + 169, 31, 134, 106, 243, 245, 16, 228, 53, 133, 143, 255, 123, 175, 19, 10, + 98, 117, 180, 38, 50, 190, 63, 70, 106, 8, 221, 78, 66, 129, 190, 181, + 165, 119, 242, 101, 19, 18, 181, 91, 223, 30, 93, 253, 74, 242, 112, 139, + 30, 121, 25, 100, 144, 32, 212, 143, 3, 96, 134, 113, 193, 190, 51, 8, + 60, 108, 88, 168, 142, 47, 217, 173, 44, 207, 174, 161, 237, 179, 147, 4, + 30, 5, 177, 202, 43, 239, 15, 135, 44, 216, 10, 183, 63, 27, 159, 195, + 56, 238, 95, 213, 45, 44, 252, 4, 101, 233, 38, 88, 66, 126, 149, 196, + 87, 211, 55, 38, 17, 92, 26, 76, 156, 183, 136, 154, 166, 219, 125, 10, + 88, 240, 97, 14, 86, 67, 4, 74, 236, 71, 72, 10, 49, 18, 158, 148, + 128, 15, 241, 17, 9, 236, 243, 22, 116, 160, 65, 166, 34, 113, 76, 41, + 100, 153, 184, 22, 62, 252, 220, 47, 180, 124, 103, 242, 104, 13, 244, 136, + 33, 146, 33, 176, 31, 159, 235, 29, 221, 255, 182, 90, 183, 158, 186, 155, + 85, 137, 173, 129, 71, 91, 147, 17, 30, 240, 214, 110, 79, 64, 21, 129, + 97, 109, 253, 198, 203, 116, 235, 89, 166, 151, 116, 106, 194, 27, 51, 177, + 23, 119, 199, 227, 50, 143, 129, 234, 188, 217, 9, 136, 48, 115, 5, 252, + 241, 195, 116, 239, 68, 176, 55, 121, 2, 38, 229, 224, 94, 204, 200, 115, + 84, 235, 131, 172, 242, 56, 208, 41, 21, 36, 113, 156, 137, 6, 225, 132, + 4, 181, 193, 84, 10, 213, 155, 150, 72, 127, 23, 107, 255, 105, 250, 61, + 234, 211, 225, 169, 93, 63, 138, 95, 201, 74, 208, 99, 119, 184, 219, 62, + 86, 163, 142, 35, 24, 86, 92, 224, 53, 84, 57, 101, 113, 76, 26, 78, + 174, 49, 28, 234, 153, 240, 27, 114, 87, 133, 130, 78, 66, 144, 205, 152, + 171, 169, 136, 219, 142, 223, 145, 149, 196, 6, 167, 109, 52, 188, 0, 98, + 242, 254, 184, 129, 250, 63, 244, 10, 97, 188, 7, 137, 183, 165, 68, 91, + 26, 188, 230, 246, 227, 12, 217, 170, 224, 119, 135, 243, 149, 88, 67, 23, + 117, 173, 130, 164, 233, 244, 251, 11, 123, 57, 80, 111, 249, 146, 231, 213, + 158, 26, 236, 250, 213, 228, 117, 251, 101, 128, 8, 241, 251, 36, 40, 149, + 148, 60, 146, 48, 104, 121, 163, 233, 2, 24, 10, 21, 93, 137, 124, 8, + 115, 220, 255, 107, 153, 105, 6, 255, 32, 160, 96, 74, 84, 184, 31, 155, + 118, 206, 58, 131, 111, 150, 137, 145, 22, 45, 138, 211, 118, 151, 248, 189, + 64, 82, 222, 9, 137, 114, 59, 89, 77, 249, 245, 195, 146, 198, 43, 209, + 186, 151, 121, 136, 170, 81, 53, 43, 126, 15, 62, 88, 171, 206, 232, 34, + 99, 52, 6, 22, 126, 140, 32, 181, 122, 253, 230, 127, 211, 254, 61, 254, + 108, 114, 38, 214, 164, 244, 87, 243, 187, 185, 57, 105, 24, 244, 59, 254, + 92, 143, 235, 38, 70, 177, 126, 123, 61, 243, 45, 127, 76, 127, 39, 45, + 254, 239, 67, 221, 24, 81, 24, 130, 247, 106, 239, 93, 18, 57, 242, 4, + 223, 131, 86, 249, 241, 81, 149, 230, 154, 17, 14, 179, 194, 234, 17, 85, + 188, 33, 162, 62, 73, 157, 253, 248, 111, 97, 205, 47, 74, 223, 192, 185, + 212, 153, 240, 156, 104, 64, 46, 209, 146, 56, 27, 21, 184, 95, 107, 95, + 101, 243, 133, 146, 194, 240, 51, 109, 158, 225, 18, 80, 66, 4, 79, 252, + 174, 187, 55, 230, 54, 51, 42, 87, 34, 159, 155, 184, 118, 167, 150, 46, + 32, 156, 244, 124, 222, 84, 247, 12, 231, 119, 237, 135, 225, 227, 97, 178, + 37, 208, 112, 126, 32, 227, 60, 239, 194, 183, 169, 208, 221, 250, 180, 56, + 137, 67, 153, 170, 242, 54, 55, 48, 219, 79, 106, 249, 250, 56, 130, 184, + 43, 56, 114, 175, 122, 249, 107, 188, 63, 169, 25, 43, 68, 61, 246, 47, + 191, 117, 150, 7, 163, 144, 42, 186, 5, 195, 11, 68, 215, 219, 87, 213, + 42, 84, 99, 37, 29, 78, 34, 180, 131, 15, 171, 186, 225, 163, 204, 225, + 72, 198, 227, 122, 245, 4, 133, 40, 134, 17, 61, 112, 55, 159, 37, 118, + 112, 173, 210, 126, 9, 23, 209, 65, 14, 109, 16, 247, 254, 45, 170, 33, + 143, 35, 107, 134, 51, 132, 135, 226, 40, 112, 156, 122, 5, 31, 37, 113, + 24, 1, 153, 3, 180, 227, 249, 172, 93, 20, 79, 126, 42, 254, 100, 80, + 86, 180, 123, 71, 213, 32, 178, 28, 63, 75, 177, 246, 25, 119, 33, 236, + 194, 31, 94, 169, 97, 96, 42, 29, 165, 234, 199, 12, 76, 8, 242, 229, + 160, 130, 169, 76, 120, 159, 25, 18, 36, 182, 222, 210, 105, 251, 2, 40, + 111, 212, 249, 119, 48, 137, 50, 71, 146, 216, 47, 18, 60, 194, 18, 119, + 197, 216, 84, 170, 143, 241, 61, 207, 206, 238, 51, 39, 145, 171, 81, 108, + 64, 0, 229, 83, 190, 81, 149, 27, 77, 44, 34, 134, 178, 250, 9, 244, + 128, 175, 124, 28, 41, 116, 254, 30, 162, 88, 207, 231, 222, 155, 224, 234, + 201, 56, 119, 191, 190, 158, 195, 16, 153, 152, 99, 244, 60, 207, 205, 133, + 34, 101, 0, 104, 144, 141, 121, 168, 44, 40, 234, 49, 35, 136, 39, 242, + 14, 198, 188, 124, 161, 135, 113, 180, 68, 218, 10, 47, 223, 190, 0, 238, + 109, 149, 149, 25, 14, 218, 109, 85, 106, 125, 45, 29, 63, 122, 74, 184, + 39, 153, 72, 81, 69, 212, 62, 80, 161, 110, 103, 56, 254, 7, 198, 201, + 47, 202, 145, 147, 115, 7, 252, 21, 157, 211, 102, 40, 117, 116, 41, 110, + 189, 45, 41, 128, 46, 18, 40, 228, 43, 159, 202, 90, 114, 78, 193, 9, + 237, 172, 59, 89, 50, 218, 47, 142, 139, 118, 146, 201, 8, 158, 116, 71, + 133, 105, 177, 199, 24, 202, 219, 64, 136, 101, 162, 11, 225, 13, 60, 217, + 13, 125, 9, 38, 224, 90, 78, 166, 145, 101, 167, 132, 24, 58, 73, 19, + 2, 185, 83, 148, 110, 133, 191, 76, 71, 18, 168, 103, 0, 123, 195, 39, + 41, 243, 215, 62, 38, 156, 101, 42, 144, 43, 125, 154, 46, 152, 74, 242, + 251, 158, 180, 189, 228, 165, 64, 75, 220, 184, 160, 9, 23, 57, 138, 16, + 88, 240, 5, 234, 106, 188, 171, 120, 55, 203, 43, 72, 33, 67, 129, 26, + 242, 128, 89, 144, 226, 129, 58, 143, 110, 185, 216, 158, 238, 175, 34, 121, + 59, 49, 76, 178, 81, 88, 181, 23, 219, 66, 1, 228, 34, 143, 250, 41, + 77, 7, 245, 65, 3, 203, 53, 144, 140, 194, 71, 27, 10, 175, 218, 149, + 242, 213, 150, 9, 199, 22, 202, 155, 5, 44, 23, 111, 102, 5, 150, 32, + 62, 31, 220, 1, 129, 151, 109, 27, 215, 54, 235, 104, 157, 123, 8, 89, + 94, 161, 197, 0, 163, 75, 124, 41, 240, 192, 109, 9, 202, 124, 25, 82, + 95, 243, 170, 63, 91, 248, 4, 63, 47, 208, 243, 61, 85, 62, 107, 32, + 87, 19, 208, 87, 120, 234, 108, 244, 44, 158, 238, 91, 185, 219, 105, 13, + 254, 85, 208, 93, 148, 144, 160, 98, 237, 72, 27, 59, 119, 22, 99, 52, + 193, 190, 57, 171, 46, 247, 180, 126, 30, 16, 200, 88, 35, 212, 215, 253, + 218, 25, 96, 40, 44, 53, 29, 129, 153, 154, 197, 238, 84, 201, 244, 106, + 184, 178, 127, 54, 198, 60, 160, 98, 4, 229, 110, 220, 225, 26, 254, 238, + 123, 69, 248, 222, 43, 122, 207, 63, 166, 246, 171, 129, 231, 7, 89, 132, + 245, 76, 55, 174, 184, 93, 139, 221, 250, 11, 86, 239, 248, 14, 98, 226, + 66, 146, 45, 59, 106, 78, 6, 253, 6, 128, 53, 174, 7, 36, 100, 130, + 22, 47, 157, 147, 27, 31, 15, 97, 122, 46, 137, 84, 126, 104, 48, 217, + 236, 131, 51, 253, 147, 23, 35, 133, 43, 183, 124, 197, 150, 85, 170, 39, + 96, 227, 44, 130, 51, 83, 224, 22, 177, 39, 65, 125, 98, 28, 162, 56, + 25, 112, 81, 50, 28, 118, 184, 45, 236, 226, 87, 117, 111, 219, 157, 34, + 224, 77, 68, 59, 91, 80, 177, 178, 188, 203, 247, 133, 130, 15, 61, 125, + 252, 18, 201, 87, 157, 158, 47, 5, 151, 104, 231, 127, 161, 154, 172, 224, + 74, 95, 195, 121, 175, 200, 18, 26, 240, 194, 222, 85, 189, 238, 106, 136, + 195, 28, 170, 10, 115, 25, 236, 203, 127, 254, 103, 79, 175, 57, 159, 102, + 193, 106, 136, 130, 195, 16, 19, 14, 240, 130, 74, 217, 154, 5, 217, 88, + 21, 113, 205, 138, 241, 209, 39, 255, 182, 100, 41, 243, 199, 191, 7, 123, + 185, 7, 186, 28, 32, 71, 236, 16, 220, 222, 5, 122, 74, 55, 95, 19, + 230, 127, 201, 130, 180, 143, 142, 149, 229, 43, 81, 95, 32, 138, 165, 42, + 136, 231, 106, 34, 90, 135, 60, 60, 105, 191, 50, 195, 62, 230, 189, 100, + 41, 110, 61, 204, 139, 237, 185, 208, 136, 61, 249, 12, 20, 230, 48, 141, + 65, 17, 204, 126, 215, 73, 77, 129, 49, 230, 39, 247, 222, 109, 50, 151, + 255, 246, 141, 254, 233, 117, 156, 172, 113, 74, 72, 133, 218, 227, 4, 192, + 27, 185, 21, 99, 61, 34, 52, 112, 74, 18, 149, 38, 195, 43, 154, 8, + 16, 189, 142, 139, 167, 137, 2, 155, 165, 1, 255, 158, 107, 131, 141, 112, + 87, 102, 97, 12, 228, 30, 143, 60, 14, 238, 183, 145, 88, 116, 187, 64, + 138, 136, 138, 24, 16, 241, 126, 37, 103, 99, 203, 164, 198, 129, 140, 189, + 18, 178, 241, 154, 7, 81, 8, 75, 196, 131, 121, 19, 52, 90, 125, 71, + 179, 8, 102, 149, 117, 88, 2, 58, 115, 41, 254, 118, 205, 28, 244, 153, + 79, 179, 136, 194, 59, 55, 233, 48, 87, 218, 151, 218, 172, 109, 72, 156, + 112, 175, 129, 111, 124, 151, 112, 69, 175, 237, 175, 208, 35, 15, 70, 189, + 245, 118, 229, 51, 121, 237, 106, 57, 190, 157, 42, 37, 107, 108, 240, 142, + 180, 123, 58, 243, 99, 76, 153, 94, 235, 148, 3, 146, 198, 250, 3, 176, + 73, 105, 64, 3, 129, 155, 69, 66, 114, 55, 53, 31, 200, 171, 9, 127, + 227, 81, 238, 0, 29, 54, 79, 184, 213, 44, 21, 21, 106, 118, 193, 193, + 132, 216, 89, 39, 107, 40, 29, 198, 229, 184, 123, 32, 225, 148, 78, 40, + 236, 108, 100, 112, 139, 33, 176, 201, 41, 56, 180, 87, 100, 161, 247, 181, + 48, 215, 32, 88, 3, 2, 69, 189, 162, 185, 155, 129, 131, 151, 170, 201, + 203, 192, 141, 27, 38, 21, 174, 100, 48, 138, 216, 113, 123, 137, 161, 92, + 153, 129, 184, 21, 205, 18, 190, 184, 189, 57, 130, 168, 67, 161, 16, 207, + 223, 35, 254, 40, 169, 65, 104, 178, 164, 88, 198, 40, 58, 221, 211, 96, + 91, 98, 147, 157, 193, 121, 211, 28, 185, 217, 84, 58, 236, 70, 181, 35, + 58, 27, 111, 52, 213, 103, 93, 154, 18, 60, 201, 180, 29, 28, 85, 126, + 170, 190, 231, 64, 27, 191, 83, 158, 125, 124, 43, 172, 198, 25, 151, 108, + 116, 7, 164, 114, 92, 215, 197, 222, 31, 231, 41, 112, 42, 172, 207, 164, + 87, 123, 138, 156, 78, 44, 131, 127, 155, 114, 138, 219, 52, 223, 150, 230, + 94, 165, 103, 45, 139, 238, 161, 208, 117, 178, 225, 67, 90, 90, 110, 176, + 20, 110, 4, 189, 194, 138, 12, 168, 150, 181, 139, 54, 241, 243, 87, 19, + 136, 251, 68, 1, 239, 85, 161, 139, 67, 117, 239, 162, 214, 96, 205, 66, + 79, 13, 47, 16, 72, 171, 33, 246, 93, 197, 65, 115, 108, 87, 83, 116, + 49, 66, 34, 18, 101, 65, 24, 178, 147, 34, 61, 242, 51, 246, 191, 249, + 164, 200, 210, 150, 146, 46, 157, 137, 147, 161, 25, 101, 217, 142, 125, 241, + 73, 115, 83, 86, 208, 167, 233, 77, 109, 89, 197, 219, 108, 206, 54, 99, + 113, 101, 77, 41, 251, 24, 203, 179, 28, 109, 62, 248, 113, 197, 82, 35, + 89, 132, 11, 184, 194, 237, 142, 71, 81, 173, 36, 220, 103, 66, 254, 78, + 252, 105, 211, 89, 149, 132, 218, 43, 45, 77, 64, 137, 248, 238, 145, 172, + 64, 78, 123, 225, 161, 166, 202, 94, 210, 227, 36, 254, 153, 230, 23, 21, + 82, 125, 167, 115, 10, 25, 141, 144, 226, 25, 151, 22, 157, 162, 2, 250, + 16, 161, 48, 111, 121, 9, 191, 229, 41, 136, 83, 163, 165, 10, 195, 34, + 56, 145, 166, 99, 184, 180, 180, 159, 95, 110, 17, 46, 227, 245, 97, 207, + 27, 113, 121, 55, 196, 29, 248, 171, 108, 250, 236, 1, 31, 108, 15, 34, + 233, 32, 250, 127, 67, 159, 151, 145, 5, 171, 219, 102, 159, 137, 231, 130, + 229, 177, 209, 253, 150, 217, 76, 62, 111, 42, 25, 152, 169, 83, 245, 164, + 127, 61, 128, 35, 234, 8, 69, 152, 103, 107, 18, 98, 101, 214, 205, 136, + 68, 165, 54, 48, 189, 59, 29, 254, 128, 255, 249, 46, 23, 246, 29, 131, + 185, 27, 160, 235, 16, 52, 232, 247, 100, 230, 137, 91, 111, 48, 202, 31, + 126, 167, 162, 45, 159, 66, 215, 176, 32, 5, 255, 82, 108, 31, 184, 89, + 6, 73, 8, 209, 86, 202, 122, 111, 132, 39, 140, 160, 74, 148, 254, 21, + 33, 80, 180, 165, 241, 182, 74, 205, 243, 194, 17, 216, 113, 8, 239, 190, + 34, 158, 31, 58, 223, 249, 51, 74, 174, 191, 157, 185, 12, 98, 190, 135, + 91, 198, 25, 221, 76, 118, 88, 240, 184, 188, 70, 92, 36, 208, 124, 43, + 228, 200, 86, 193, 178, 251, 115, 233, 240, 11, 134, 91, 230, 141, 195, 161, + 255, 12, 103, 85, 187, 84, 129, 202, 48, 85, 155, 242, 226, 185, 109, 126, + 2, 8, 174, 221, 203, 67, 182, 52, 114, 243, 219, 32, 89, 183, 125, 18, + 209, 200, 99, 116, 123, 185, 17, 250, 250, 223, 129, 221, 147, 249, 142, 238, + 25, 230, 85, 85, 141, 248, 144, 13, 241, 3, 10, 253, 74, 96, 82, 115, + 210, 221, 17, 79, 213, 119, 27, 192, 55, 41, 161, 125, 167, 87, 45, 10, + 246, 22, 76, 245, 83, 4, 160, 242, 62, 221, 89, 206, 80, 235, 33, 34, + 81, 125, 28, 117, 233, 167, 89, 6, 132, 138, 130, 88, 227, 245, 44, 138, + 180, 42, 215, 4, 177, 9, 167, 135, 173, 234, 185, 119, 100, 108, 4, 237, + 145, 52, 227, 61, 231, 130, 77, 97, 204, 175, 136, 225, 27, 29, 36, 142, + 151, 129, 170, 105, 233, 88, 57, 122, 219, 60, 16, 70, 253, 218, 123, 188, + 49, 210, 121, 115, 150, 249, 213, 246, 76, 2, 197, 196, 24, 169, 143, 175, + 230, 138, 32, 81, 191, 13, 166, 211, 252, 110, 84, 221, 244, 13, 45, 116, + 242, 123, 18, 153, 163, 187, 46, 33, 28, 160, 219, 179, 85, 166, 2, 125, + 92, 99, 147, 61, 4, 200, 245, 135, 172, 187, 4, 101, 102, 85, 79, 168, + 53, 222, 129, 150, 252, 253, 252, 45, 39, 64, 33, 104, 69, 239, 180, 71, + 234, 177, 245, 185, 59, 238, 88, 65, 58, 156, 84, 238, 150, 46, 236, 65, + 229, 33, 221, 168, 102, 249, 163, 155, 36, 189, 54, 211, 154, 247, 69, 45, + 47, 140, 119, 63, 143, 129, 163, 38, 120, 88, 216, 66, 117, 118, 176, 93, + 153, 42, 129, 198, 45, 203, 26, 150, 43, 17, 53, 104, 196, 82, 234, 59, + 129, 81, 14, 104, 229, 8, 204, 187, 8, 168, 112, 18, 211, 154, 195, 181, + 87, 241, 234, 148, 68, 229, 231, 23, 134, 14, 97, 119, 22, 48, 123, 17, + 115, 105, 180, 124, 135, 51, 177, 104, 187, 23, 210, 76, 161, 8, 36, 57, + 218, 252, 142, 236, 154, 178, 119, 129, 189, 255, 208, 56, 25, 70, 68, 50, + 57, 172, 77, 154, 163, 80, 33, 180, 118, 57, 105, 97, 5, 50, 158, 185, + 226, 119, 237, 163, 47, 79, 233, 114, 160, 246, 93, 238, 197, 217, 240, 55, + 121, 37, 138, 104, 245, 181, 30, 133, 129, 94, 97, 31, 188, 121, 119, 74, + 227, 167, 196, 194, 108, 185, 63, 242, 0, 224, 8, 162, 49, 173, 57, 250, + 12, 113, 238, 241, 0, 180, 180, 198, 57, 180, 248, 243, 214, 122, 103, 81, + 205, 243, 232, 213, 39, 122, 142, 107, 4, 63, 123, 147, 22, 78, 174, 200, + 33, 27, 16, 76, 139, 230, 32, 101, 246, 228, 246, 89, 15, 30, 11, 87, + 174, 70, 195, 104, 14, 26, 209, 149, 19, 254, 121, 62, 186, 224, 56, 247, + 10, 237, 102, 83, 215, 211, 22, 123, 161, 52, 251, 122, 142, 228, 191, 93, + 151, 174, 176, 166, 64, 184, 254, 113, 140, 214, 109, 159, 126, 201, 95, 245, + 167, 180, 165, 106, 61, 83, 143, 239, 68, 254, 0, 201, 237, 162, 231, 108, + 152, 131, 248, 39, 149, 131, 80, 224, 41, 14, 157, 96, 16, 251, 139, 15, + 153, 45, 29, 84, 116, 154, 221, 234, 127, 39, 10, 244, 3, 92, 154, 93, + 125, 209, 252, 144, 73, 139, 47, 93, 98, 78, 7, 61, 173, 117, 46, 155, + 73, 76, 127, 202, 5, 223, 113, 215, 86, 54, 82, 0, 105, 16, 52, 226, + 140, 232, 53, 23, 76, 117, 212, 139, 183, 112, 95, 162, 174, 153, 104, 4, + 241, 133, 159, 188, 4, 147, 92, 125, 133, 104, 26, 241, 130, 13, 239, 96, + 235, 36, 195, 74, 193, 126, 54, 27, 55, 190, 97, 44, 26, 106, 31, 76, + 244, 174, 179, 1, 97, 168, 114, 14, 65, 60, 199, 182, 133, 130, 65, 175, + 95, 224, 125, 74, 157, 34, 99, 26, 135, 160, 188, 244, 114, 175, 211, 194, + 74, 97, 182, 244, 93, 3, 219, 223, 154, 204, 10, 132, 233, 165, 23, 204, + 187, 163, 179, 23, 72, 137, 22, 40, 123, 77, 216, 95, 44, 20, 55, 213, + 165, 125, 17, 237, 77, 140, 2, 146, 193, 104, 9, 83, 40, 126, 177, 137, + 53, 89, 59, 23, 49, 80, 240, 168, 70, 97, 250, 36, 161, 17, 228, 161, + 136, 213, 43, 118, 106, 198, 251, 68, 223, 34, 79, 123, 118, 91, 222, 236, + 73, 236, 175, 255, 248, 249, 96, 53, 245, 248, 238, 12, 106, 127, 183, 1, + 31, 193, 14, 126, 7, 19, 252, 102, 191, 74, 208, 115, 140, 76, 133, 179, + 82, 5, 83, 122, 154, 82, 37, 19, 171, 190, 177, 177, 233, 248, 175, 214, + 93, 17, 121, 167, 249, 165, 149, 191, 145, 188, 218, 99, 154, 55, 109, 202, + 12, 17, 56, 107, 124, 137, 156, 233, 85, 18, 237, 207, 9, 72, 10, 218, + 98, 58, 70, 254, 207, 179, 61, 201, 250, 163, 135, 215, 130, 182, 47, 93, + 123, 14, 251, 252, 34, 240, 172, 151, 111, 127, 19, 6, 165, 96, 254, 15, + 32, 153, 247, 91, 200, 78, 169, 160, 28, 70, 146, 251, 174, 49, 54, 98, + 93, 161, 19, 105, 195, 62, 196, 38, 84, 53, 122, 177, 158, 179, 113, 93, + 91, 102, 90, 119, 52, 120, 247, 208, 228, 233, 97, 240, 187, 205, 14, 194, + 35, 134, 229, 241, 16, 152, 130, 206, 63, 93, 110, 21, 52, 170, 67, 99, + 214, 121, 230, 201, 133, 173, 143, 225, 81, 184, 139, 105, 226, 58, 237, 106, + 16, 91, 163, 15, 4, 63, 94, 186, 80, 219, 85, 209, 183, 129, 122, 39, + 8, 140, 180, 203, 167, 223, 148, 74, 147, 29, 237, 108, 105, 143, 229, 254, + 104, 243, 111, 210, 11, 185, 158, 151, 90, 47, 43, 233, 91, 18, 119, 144, + 184, 63, 64, 3, 244, 225, 30, 134, 198, 210, 41, 103, 2, 31, 221, 74, + 26, 54, 18, 23, 242, 104, 39, 31, 167, 183, 209, 105, 192, 88, 219, 25, + 134, 228, 8, 222, 149, 25, 195, 141, 61, 33, 114, 213, 93, 6, 58, 12, + 191, 113, 216, 153, 39, 235, 173, 146, 34, 139, 210, 13, 59, 240, 88, 10, + 71, 72, 27, 225, 32, 70, 92, 182, 120, 151, 82, 246, 248, 93, 119, 13, + 199, 161, 48, 202, 84, 88, 226, 198, 249, 152, 165, 34, 183, 109, 9, 196, + 232, 168, 236, 241, 85, 100, 181, 81, 235, 85, 247, 85, 173, 57, 141, 145, + 116, 254, 146, 249, 161, 133, 245, 17, 117, 141, 208, 49, 245, 121, 181, 158, + 144, 197, 200, 63, 202, 119, 158, 107, 112, 56, 178, 227, 29, 87, 48, 151, + 228, 55, 194, 130, 52, 12, 35, 245, 171, 149, 90, 206, 151, 205, 184, 221, + 45, 57, 126, 64, 203, 244, 167, 172, 134, 141, 5, 145, 101, 29, 33, 133, + 90, 17, 64, 127, 152, 209, 78, 10, 131, 151, 157, 204, 231, 255, 164, 122, + 16, 78, 220, 245, 161, 229, 90, 203, 12, 205, 95, 8, 47, 51, 92, 23, + 118, 95, 211, 124, 116, 147, 74, 79, 10, 192, 217, 74, 80, 127, 17, 105, + 56, 248, 144, 72, 197, 159, 230, 19, 147, 31, 50, 239, 236, 92, 237, 131, + 159, 88, 99, 171, 76, 209, 41, 181, 194, 28, 3, 242, 137, 227, 20, 198, + 120, 6, 12, 97, 45, 210, 143, 177, 60, 83, 61, 135, 132, 187, 54, 61, + 82, 149, 193, 23, 45, 6, 95, 28, 167, 0, 67, 27, 17, 93, 241, 43, + 221, 109, 102, 179, 204, 80, 198, 60, 229, 38, 47, 100, 235, 50, 166, 193, + 79, 255, 71, 207, 116, 216, 201, 255, 134, 194, 201, 34, 169, 250, 28, 217, + 198, 176, 10, 203, 193, 197, 125, 80, 116, 149, 108, 224, 10, 195, 68, 228, + 218, 85, 146, 119, 67, 73, 118, 186, 171, 162, 86, 198, 176, 73, 41, 162, + 237, 196, 130, 32, 231, 70, 197, 139, 140, 182, 151, 221, 55, 95, 183, 58, + 43, 141, 160, 148, 193, 197, 162, 189, 62, 36, 226, 255, 214, 75, 166, 163, + 78, 30, 253, 52, 8, 190, 55, 241, 60, 187, 226, 34, 177, 102, 155, 56, + 165, 51, 183, 2, 181, 247, 125, 53, 36, 206, 73, 32, 19, 20, 204, 228, + 105, 254, 34, 201, 161, 175, 232, 223, 216, 103, 247, 13, 68, 49, 206, 172, + 122, 11, 17, 3, 55, 101, 94, 39, 18, 183, 214, 16, 149, 252, 137, 39, + 205, 84, 114, 80, 101, 246, 222, 173, 145, 229, 199, 73, 91, 219, 123, 235, + 45, 190, 39, 241, 146, 209, 124, 178, 151, 30, 19, 26, 112, 150, 192, 183, + 237, 124, 253, 165, 28, 130, 132, 161, 157, 140, 159, 163, 87, 181, 211, 166, + 233, 0, 180, 87, 125, 229, 173, 128, 90, 23, 38, 235, 143, 31, 117, 66, + 203, 76, 150, 249, 19, 23, 45, 184, 56, 249, 220, 114, 205, 1, 215, 169, + 205, 173, 58, 188, 128, 116, 122, 184, 48, 114, 95, 167, 3, 191, 136, 238, + 124, 245, 166, 82, 191, 16, 212, 149, 183, 166, 14, 212, 255, 67, 106, 50, + 159, 172, 211, 101, 207, 198, 242, 179, 40, 1, 73, 20, 64, 185, 29, 21, + 216, 246, 154, 104, 156, 214, 231, 192, 137, 220, 150, 215, 4, 80, 110, 164, + 185, 68, 114, 110, 234, 45, 143, 171, 196, 148, 151, 237, 16, 251, 68, 221, + 100, 18, 212, 110, 59, 147, 113, 217, 152, 28, 83, 198, 211, 231, 35, 39, + 198, 19, 163, 67, 40, 24, 124, 52, 138, 161, 254, 233, 90, 24, 214, 222, + 121, 189, 95, 180, 77, 147, 21, 187, 111, 9, 184, 75, 209, 250, 81, 110, + 34, 97, 198, 132, 182, 229, 192, 208, 67, 98, 124, 108, 141, 89, 37, 124, + 11, 5, 128, 76, 13, 220, 167, 201, 182, 151, 45, 235, 37, 142, 35, 192, + 28, 209, 254, 40, 15, 22, 183, 181, 138, 144, 72, 21, 48, 9, 133, 127, + 74, 187, 19, 170, 88, 209, 119, 194, 230, 243, 237, 156, 184, 156, 46, 118, + 58, 7, 139, 163, 157, 167, 65, 249, 102, 228, 201, 27, 255, 189, 54, 151, + 168, 108, 129, 113, 106, 245, 244, 158, 176, 247, 193, 161, 94, 248, 190, 38, + 208, 177, 246, 108, 158, 199, 56, 37, 141, 101, 102, 44, 109, 144, 23, 214, + 235, 251, 210, 184, 103, 145, 248, 118, 162, 139, 84, 61, 146, 29, 70, 170, + 80, 30, 145, 156, 202, 185, 222, 87, 247, 137, 153, 98, 166, 61, 173, 200, + 164, 40, 2, 137, 226, 66, 162, 24, 172, 46, 203, 80, 176, 156, 93, 26, + 48, 69, 130, 192, 129, 84, 70, 15, 25, 224, 175, 31, 161, 110, 61, 220, + 214, 220, 152, 22, 41, 51, 57, 114, 182, 139, 129, 159, 194, 169, 133, 246, + 37, 23, 79, 90, 88, 231, 6, 252, 101, 241, 250, 168, 71, 149, 252, 196, + 126, 2, 29, 177, 70, 218, 120, 203, 72, 243, 46, 45, 149, 57, 108, 37, + 198, 38, 177, 210, 32, 252, 227, 160, 77, 174, 211, 207, 212, 82, 139, 189, + 79, 198, 116, 165, 185, 49, 188, 43, 116, 230, 182, 34, 224, 138, 216, 93, + 93, 94, 175, 10, 217, 41, 209, 177, 36, 142, 205, 241, 34, 129, 8, 91, + 78, 210, 231, 166, 188, 18, 77, 139, 201, 203, 3, 154, 131, 8, 193, 207, + 255, 98, 166, 192, 215, 206, 236, 217, 9, 19, 78, 227, 105, 146, 56, 50, + 60, 114, 20, 239, 186, 119, 113, 183, 79, 186, 126, 223, 131, 30, 217, 249, + 82, 10, 188, 238, 161, 46, 174, 96, 6, 187, 251, 234, 62, 163, 213, 55, + 71, 253, 25, 193, 26, 176, 111, 20, 167, 220, 240, 78, 243, 42, 104, 194, + 0, 62, 53, 119, 199, 9, 202, 20, 164, 55, 155, 204, 107, 120, 180, 6, + 20, 114, 122, 130, 143, 124, 89, 130, 66, 140, 43, 183, 203, 216, 78, 86, + 178, 16, 226, 159, 192, 205, 105, 113, 138, 165, 108, 18, 214, 100, 154, 71, + 150, 46, 70, 178, 181, 68, 68, 160, 253, 18, 19, 220, 253, 207, 87, 105, + 32, 239, 229, 137, 155, 176, 139, 168, 248, 143, 86, 67, 224, 146, 17, 80, + 147, 87, 30, 168, 125, 169, 91, 59, 55, 169, 142, 226, 71, 181, 114, 40, + 231, 229, 155, 27, 31, 144, 166, 96, 9, 85, 90, 152, 25, 83, 113, 15, + 65, 106, 162, 151, 74, 7, 27, 188, 221, 150, 108, 96, 102, 233, 174, 208, + 9, 170, 159, 239, 67, 230, 187, 93, 141, 102, 218, 191, 48, 22, 53, 124, + 84, 96, 110, 43, 28, 126, 26, 32, 104, 104, 65, 99, 112, 207, 167, 54, + 175, 165, 152, 105, 234, 18, 138, 148, 101, 9, 87, 32, 155, 192, 7, 100, + 101, 72, 133, 203, 170, 248, 222, 190, 243, 0, 75, 100, 38, 52, 98, 125, + 66, 185, 104, 255, 8, 184, 116, 195, 32, 239, 213, 54, 28, 185, 96, 177, + 233, 30, 210, 25, 155, 28, 128, 53, 88, 101, 146, 68, 52, 60, 55, 183, + 171, 157, 207, 128, 53, 60, 22, 100, 53, 121, 124, 205, 163, 55, 82, 162, + 96, 99, 71, 184, 243, 169, 137, 77, 191, 16, 55, 59, 220, 197, 20, 4, + 61, 89, 4, 157, 96, 171, 145, 91, 145, 19, 36, 195, 42, 132, 152, 83, + 255, 137, 64, 37, 72, 190, 82, 29, 181, 41, 175, 144, 46, 229, 236, 217, + 105, 194, 7, 118, 19, 47, 151, 238, 222, 255, 183, 236, 181, 175, 135, 91, + 55, 163, 4, 156, 190, 18, 153, 21, 178, 51, 102, 36, 62, 253, 228, 12, + 102, 230, 138, 183, 182, 253, 54, 170, 251, 50, 107, 223, 180, 177, 74, 169, + 231, 208, 76, 47, 146, 158, 251, 181, 9, 219, 240, 169, 72, 250, 241, 125, + 86, 200, 125, 166, 137, 65, 115, 18, 68, 241, 124, 51, 128, 223, 113, 239, + 201, 221, 152, 21, 114, 127, 79, 101, 44, 48, 241, 21, 221, 91, 240, 214, + 166, 119, 140, 21, 143, 155, 172, 26, 207, 233, 0, 128, 118, 45, 22, 6, + 222, 75, 90, 99, 173, 214, 121, 53, 71, 183, 253, 19, 95, 71, 66, 16, + 41, 35, 195, 9, 93, 247, 42, 150, 49, 46, 229, 73, 220, 12, 230, 51, + 109, 147, 108, 124, 102, 83, 78, 75, 67, 141, 55, 246, 155, 195, 190, 56, + 116, 59, 185, 237, 104, 78, 66, 173, 165, 178, 32, 93, 14, 10, 46, 30, + 229, 108, 50, 52, 188, 2, 244, 142, 201, 8, 245, 53, 210, 132, 15, 184, + 82, 85, 156, 142, 35, 49, 39, 183, 58, 61, 96, 143, 60, 190, 41, 152, + 9, 183, 127, 90, 157, 109, 196, 76, 36, 177, 244, 173, 63, 233, 1, 16, + 110, 216, 203, 94, 245, 195, 71, 55, 161, 149, 230, 122, 159, 133, 143, 180, + 129, 6, 111, 56, 211, 30, 13, 142, 216, 122, 87, 69, 91, 233, 254, 4, + 232, 207, 157, 32, 113, 50, 227, 233, 158, 171, 38, 228, 191, 121, 56, 165, + 222, 22, 180, 217, 111, 104, 112, 134, 12, 22, 244, 44, 234, 34, 253, 217, + 212, 140, 93, 235, 36, 54, 4, 129, 32, 91, 197, 163, 24, 71, 133, 161, + 111, 114, 29, 19, 45, 100, 10, 207, 139, 158, 219, 206, 160, 248, 94, 12, + 241, 58, 118, 141, 115, 166, 177, 78, 173, 59, 85, 81, 97, 240, 154, 231, + 79, 200, 199, 195, 205, 98, 245, 129, 246, 217, 97, 209, 249, 194, 28, 179, + 49, 248, 14, 6, 128, 61, 178, 15, 190, 32, 251, 111, 225, 148, 0, 11, + 227, 246, 146, 46, 41, 231, 24, 80, 43, 174, 228, 166, 171, 206, 72, 142, + 253, 96, 242, 181, 31, 207, 95, 66, 88, 152, 165, 67, 7, 238, 23, 114, + 50, 224, 212, 241, 202, 224, 247, 70, 215, 162, 8, 237, 121, 169, 254, 191, + 30, 19, 72, 252, 3, 109, 5, 206, 105, 130, 69, 250, 250, 232, 135, 203, + 253, 77, 102, 203, 40, 72, 128, 223, 60, 59, 83, 103, 162, 117, 47, 200, + 65, 88, 43, 168, 168, 255, 46, 166, 86, 193, 231, 227, 92, 222, 186, 44, + 20, 166, 136, 123, 193, 88, 155, 166, 185, 73, 85, 124, 253, 80, 43, 176, + 173, 191, 2, 10, 50, 101, 143, 17, 129, 56, 191, 83, 103, 183, 143, 247, + 253, 161, 1, 76, 161, 76, 127, 194, 108, 88, 138, 152, 147, 164, 65, 147, + 61, 160, 192, 44, 56, 103, 144, 51, 153, 224, 38, 97, 173, 128, 34, 85, + 89, 143, 17, 239, 200, 47, 160, 2, 151, 249, 219, 208, 116, 71, 205, 72, + 210, 178, 205, 184, 207, 19, 37, 127, 183, 21, 229, 176, 91, 196, 203, 225, + 67, 189, 94, 214, 180, 203, 140, 186, 39, 250, 66, 3, 128, 35, 206, 43, + 67, 244, 207, 157, 165, 188, 201, 173, 43, 47, 210, 139, 254, 144, 218, 62, + 55, 6, 187, 32, 128, 206, 56, 74, 66, 42, 159, 171, 108, 56, 220, 246, + 127, 127, 32, 221, 190, 33, 91, 93, 88, 36, 51, 115, 93, 47, 203, 133, + 155, 166, 13, 124, 118, 56, 182, 202, 55, 224, 226, 36, 233, 9, 200, 217, + 249, 22, 252, 209, 179, 66, 32, 30, 129, 48, 186, 232, 66, 248, 197, 120, + 168, 191, 124, 16, 232, 117, 44, 125, 188, 157, 71, 35, 245, 219, 17, 111, + 41, 159, 96, 44, 233, 3, 105, 109, 199, 182, 42, 34, 87, 218, 48, 142, + 196, 99, 37, 89, 44, 173, 184, 160, 104, 203, 224, 230, 58, 60, 213, 132, + 9, 9, 253, 251, 72, 75, 235, 224, 20, 198, 208, 178, 42, 253, 126, 105, + 227, 171, 89, 93, 42, 222, 185, 232, 8, 248, 83, 78, 132, 37, 38, 173, + 67, 116, 185, 216, 47, 192, 196, 221, 172, 26, 5, 191, 41, 33, 114, 40, + 139, 22, 147, 173, 234, 41, 252, 118, 244, 73, 73, 237, 42, 6, 123, 228, + 213, 210, 202, 65, 195, 253, 112, 57, 202, 85, 247, 15, 160, 237, 138, 76, + 70, 94, 230, 163, 112, 217, 134, 78, 213, 55, 68, 198, 29, 195, 16, 138, + 162, 19, 34, 158, 144, 131, 64, 244, 80, 85, 63, 175, 47, 63, 233, 175, + 168, 190, 39, 4, 47, 200, 9, 161, 248, 198, 182, 166, 56, 23, 5, 121, + 188, 46, 90, 56, 216, 72, 203, 107, 212, 171, 110, 134, 255, 24, 243, 30, + 188, 55, 111, 8, 238, 198, 201, 180, 150, 230, 191, 248, 10, 82, 178, 247, + 114, 216, 83, 183, 24, 188, 131, 26, 246, 210, 42, 30, 111, 181, 215, 129, + 41, 21, 207, 15, 83, 86, 252, 169, 220, 246, 117, 114, 254, 143, 193, 60, + 123, 226, 202, 18, 77, 221, 135, 84, 180, 229, 79, 143, 241, 219, 217, 85, + 158, 63, 5, 245, 134, 63, 102, 68, 145, 100, 35, 13, 127, 241, 76, 211, + 204, 45, 125, 175, 128, 142, 244, 189, 203, 138, 63, 249, 2, 174, 167, 171, + 32, 131, 12, 250, 248, 198, 245, 3, 98, 4, 111, 244, 226, 122, 136, 58, + 189, 234, 244, 106, 117, 92, 97, 191, 247, 95, 114, 20, 151, 51, 67, 174, + 236, 109, 252, 215, 107, 183, 174, 254, 59, 22, 158, 203, 152, 194, 135, 200, + 61, 193, 249, 199, 24, 167, 119, 223, 205, 135, 112, 51, 118, 120, 253, 75, + 61, 101, 172, 213, 36, 226, 135, 54, 229, 214, 151, 9, 2, 197, 84, 22, + 207, 55, 182, 191, 53, 243, 63, 53, 13, 93, 121, 44, 174, 237, 192, 138, + 116, 208, 200, 134, 94, 34, 122, 110, 157, 231, 169, 177, 180, 203, 167, 125, + 73, 44, 57, 104, 204, 174, 36, 172, 47, 21, 36, 220, 92, 62, 191, 77, + 113, 5, 32, 8, 115, 61, 235, 237, 27, 76, 69, 187, 117, 72, 26, 49, + 217, 249, 130, 134, 139, 27, 229, 183, 146, 80, 3, 154, 25, 26, 52, 175, + 157, 1, 91, 126, 165, 6, 168, 134, 60, 32, 227, 68, 161, 126, 207, 247, + 160, 103, 105, 156, 129, 211, 220, 155, 222, 60, 184, 255, 149, 9, 116, 201, + 151, 42, 126, 0, 36, 167, 178, 40, 160, 5, 115, 82, 176, 207, 38, 10, + 213, 132, 57, 255, 138, 4, 204, 32, 33, 128, 174, 99, 94, 161, 237, 0, + 230, 209, 198, 89, 167, 80, 193, 116, 195, 111, 204, 241, 169, 46, 117, 108, + 244, 247, 12, 216, 106, 50, 242, 209, 61, 42, 214, 33, 25, 38, 138, 217, + 225, 105, 76, 244, 126, 252, 253, 57, 238, 107, 166, 158, 250, 132, 105, 91, + 184, 209, 217, 5, 202, 84, 254, 51, 233, 58, 2, 141, 130, 47, 97, 125, + 244, 95, 177, 68, 9, 213, 115, 118, 215, 70, 9, 64, 113, 139, 19, 165, + 231, 204, 191, 129, 15, 235, 143, 225, 241, 75, 168, 227, 126, 58, 201, 98, + 16, 227, 27, 148, 166, 1, 34, 110, 84, 120, 11, 181, 150, 111, 167, 184, + 49, 244, 231, 192, 44, 59, 41, 122, 58, 12, 185, 180, 54, 122, 106, 201, + 2, 65, 118, 129, 149, 139, 31, 201, 205, 90, 96, 76, 23, 43, 218, 15, + 233, 202, 103, 84, 18, 122, 25, 218, 38, 252, 222, 104, 172, 96, 30, 57, + 205, 130, 106, 183, 189, 230, 67, 63, 162, 142, 46, 199, 45, 244, 3, 26, + 208, 119, 15, 16, 29, 196, 178, 90, 41, 94, 193, 64, 51, 205, 136, 157 +}; + diff --git a/all_pairs/source/rijndael_dec/rijndael_dec.c b/all_pairs/source/rijndael_dec/rijndael_dec.c new file mode 100644 index 0000000..4082eff --- /dev/null +++ b/all_pairs/source/rijndael_dec/rijndael_dec.c @@ -0,0 +1,195 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: rijndael_enc + + Author: Dr Brian Gladman + + Function: rijndael_dec is an implementation of the AES decryption + algorithm (Rijndael). + + Source: security section of MiBench + + Changes: Add computation of a checksum, refactoring + + License: see below + +*/ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +#include "../extra.h" +#include "aes.h" +#include "rijndael_dec_libc.h" + +/* + Global variable definitions +*/ +unsigned char rijndael_dec_key[32]; +int rijndael_dec_key_len; + +extern unsigned char rijndael_dec_data[]; +struct rijndael_dec_FILE rijndael_dec_fin; + +int rijndael_dec_checksum = 0; + +/* + Forward declaration of functions +*/ +void rijndael_dec_init( void ); +int rijndael_dec_return( void ); +void rijndael_dec_fillrand( unsigned char *buf, int len ); +void rijndael_dec_decfile( struct rijndael_dec_FILE *fin, struct aes *ctx ); +void rijndael_dec_main( void ); + +void rijndael_dec_init( void ) +{ + /* create a pseudo-file for the input*/ + rijndael_dec_fin.data = rijndael_dec_data; + rijndael_dec_fin.size = 32768; + rijndael_dec_fin.cur_pos = 0; + + unsigned i; + volatile int x = 0; + rijndael_dec_fin.size ^= x; + _Pragma( "loopbound min 32768 max 32768" ) + for ( i = 0; i < rijndael_dec_fin.size; i++ ) + rijndael_dec_fin.data[i] ^= x; + + /* this is a pointer to the hexadecimal key digits */ + const volatile char *cp = + "1234567890abcdeffedcba09876543211234567890abcdeffedcba0987654321"; + char ch; + int by = 0; + + i = 0; /* this is a count for the input digits processed */ + _Pragma( "loopbound min 64 max 64" ) + while ( i < 64 && *cp ) { /* the maximum key length is 32 bytes and */ + /* hence at most 64 hexadecimal digits */ + ch = rijndael_dec_toupper( *cp++ ); /* process a hexadecimal digit */ + if ( ch >= '0' && ch <= '9' ) + by = ( by << 4 ) + ch - '0'; + else + if ( ch >= 'A' && ch <= 'F' ) + by = ( by << 4 ) + ch - 'A' + 10; + else { /* error if not hexadecimal */ + rijndael_dec_checksum = -2; + return; + } + + /* store a key byte for each pair of hexadecimal digits */ + if ( i++ & 1 ) + rijndael_dec_key[i / 2 - 1] = by & 0xff; + } + + if ( *cp ) { + rijndael_dec_checksum = -3; + return; + } else + if ( i < 32 || ( i & 15 ) ) { + rijndael_dec_checksum = -4; + return; + } + + rijndael_dec_key_len = i / 2; +} + +int rijndael_dec_return( void ) +{ + return ( ( rijndael_dec_checksum == ( int )262180 ) ? 0 : -1 ); +} + +void rijndael_dec_decfile( struct rijndael_dec_FILE *fin, struct aes *ctx ) +{ + unsigned char inbuf1[16], inbuf2[16], outbuf[16], *bp1, *bp2, *tp; + int i; + + + rijndael_dec_fread( inbuf1, 1, 16, fin ); + + i = rijndael_dec_fread( inbuf2, 1, 16, + fin ); /* read 1st encrypted file block */ + + if ( i && i != 16 ) { + rijndael_dec_checksum = -10; + return; + } + + rijndael_dec_decrypt( inbuf2, outbuf, + ctx ); /* decrypt it */ + + rijndael_dec_checksum += outbuf[15]; + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor with previous input */ + outbuf[i] ^= inbuf1[i]; + + bp1 = inbuf1; /* set up pointers to two input buffers */ + bp2 = inbuf2; + + /* TODO: this is necessarily an input-dependent loop bound */ + _Pragma( "loopbound min 19491 max 91491" ) + while ( 1 ) { + i = rijndael_dec_fread( bp1, 1, 16, fin ); /* read next encrypted block */ + /* to first input buffer */ + if ( i != 16 ) /* no more bytes in input - the decrypted */ + break; /* partial final buffer needs to be output */ + + /* if a block has been read the previous block must have been */ + /* full lnegth so we can now write it out */ + + rijndael_dec_decrypt( bp1, outbuf, ctx ); /* decrypt the new input block and */ + + rijndael_dec_checksum += outbuf[15]; + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor it with previous input block */ + outbuf[i] ^= bp2[i]; + + /* swap buffer pointers */ + tp = bp1, bp1 = bp2, bp2 = tp; + } +} + +void _Pragma( "entrypoint" ) rijndael_dec_main( void ) +{ + struct aes ctx[1]; + + /* decryption in Cipher Block Chaining mode */ + rijndael_dec_set_key( rijndael_dec_key, rijndael_dec_key_len, dec, ctx ); + rijndael_dec_decfile( &rijndael_dec_fin, ctx ); +} + +int main(int argc, char** argv) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= 'a' ) && ( c <= 'z' ) ) + return c - 'a' + 'A'; + return c; +} + +unsigned long rijndael_dec_fread( void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_read = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 10 max 16" ) + while ( i < stream->cur_pos + number_of_chars_to_read ) + ( ( unsigned char * )ptr )[i2++] = stream->data[i++]; + stream->cur_pos += number_of_chars_to_read; + return number_of_chars_to_read; +} + +unsigned long rijndael_dec_fwrite( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_write = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 0 max 0" ) + while ( i < stream->cur_pos + number_of_chars_to_write ) + stream->data[i++] = ( ( unsigned char * )ptr )[i2++]; + stream->cur_pos += number_of_chars_to_write; + return number_of_chars_to_write; +} + +int rijndael_dec_fseek( struct rijndael_dec_FILE *stream, long int offset, + Origin origin ) +{ + if ( origin == RIJNDAEL_DEC_SEEK_SET ) { + stream->cur_pos = offset; + return 0; + } else + if ( origin == RIJNDAEL_DEC_SEEK_CUR ) { + stream->cur_pos += offset; + return 0; + } else + if ( origin == RIJNDAEL_DEC_SEEK_END ) { + stream->cur_pos = stream->size + offset; + return 0; + } + return -1; +} + +int rijndael_dec_fgetpos( struct rijndael_dec_FILE *stream, + unsigned *position ) +{ + *position = stream->cur_pos; + return 0; +} + +int rijndael_dec_feof( struct rijndael_dec_FILE *stream ) +{ + return stream->cur_pos == stream->size ? 1 : 0; +} diff --git a/all_pairs/source/rijndael_dec/rijndael_dec_libc.h b/all_pairs/source/rijndael_dec/rijndael_dec_libc.h new file mode 100644 index 0000000..eb7b8d6 --- /dev/null +++ b/all_pairs/source/rijndael_dec/rijndael_dec_libc.h @@ -0,0 +1,24 @@ +#ifndef RIJNDAEL_DEC_LIBC_H +#define RIJNDAEL_DEC_LIBC_H + +int rijndael_dec_toupper ( int c ); + +enum _Origin_ { RIJNDAEL_DEC_SEEK_SET, RIJNDAEL_DEC_SEEK_CUR, RIJNDAEL_DEC_SEEK_END }; +typedef enum _Origin_ Origin; +struct rijndael_dec_FILE { + unsigned char *data; + unsigned long size; + unsigned cur_pos; +}; + +unsigned long rijndael_dec_fread ( void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ); +unsigned long rijndael_dec_fwrite ( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ); +int rijndael_dec_fseek ( struct rijndael_dec_FILE *stream, long int offset, + Origin origin ); +int rijndael_dec_fgetpos( struct rijndael_dec_FILE *stream, + unsigned *position ); +int rijndael_dec_feof ( struct rijndael_dec_FILE *stream ); + +#endif // RIJNDAEL_DEC_LIBC_H diff --git a/all_pairs/source/rijndael_enc/ChangeLog.txt b/all_pairs/source/rijndael_enc/ChangeLog.txt new file mode 100644 index 0000000..6ea9ed4 --- /dev/null +++ b/all_pairs/source/rijndael_enc/ChangeLog.txt @@ -0,0 +1,98 @@ +File: rijndael_encoder.c +Source: security section of MiBench + +2016-02-26: +- Remove commented-out code +- Prefix functions with "rijndael_enc" +- Compute a checksum and return it from main +- Change return type of rijndael_enc_encfile to void +- Move functionality from function main into functions + rijndael_enc_init, rijndael_enc_main, and rijndael_enc_return +- Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions +- Added function prototypes +- Applied code formatting with astyle as in the example +- Added general TACLeBench header to beginning of source code +- Rename to rijndael_enc.c + +2016-03-15: +- Return 0 if checksum is as expected, -1 otherwise +- Add entrypoint pragma +- Make inputs volatile (or touch them with a volatile) to rule out + optimizations + +2016-04-20: +- Cast "expected" return value to int for comparison +- Make loop counter in rijndael_enc_init unsigned + +Files: aes.c, aes.h, aestab.h +Source: security section of MiBench + +2016-02-26: +- Remove unused defines UNROLL, PARTIAL_UNROLL +- Remove defines FIXED_TABLES, FF_TABLES, ARRAYS, FOUR_TABLES, + FOUR_LR_TABLES, FOUR_IM_TABLES +- Remove (undefined) define ONE_TABLE, ONE_LR_TABLE , ONE_IM_TABLE +- Assume BLOCK_SIZE is always 16 +- Remove unused define "unused" +- Remove INTERNAL_BYTE_ORDER, EXTERNAL_BYTE_ORDER, AES_BIG_ENDIAN, + AES_LITTLE_ENDIAN (assume internal == external == little endian) +- Remove defines AES_DLL and AES_IN_CPP +- Remove "#if defined(__cplusplus)" +- Replace macros c_name and cf_dec with their definition +- Remove some stale comments +- Remove defines no_table and one_table +- Remove prototypes for unusedfunctions decrypt and set_blk +- Prefix all functions and global variables with "rijndael_enc" +- Break lines in overly long macros +- Protect macros +- Applied code formatting with astyle as in the example + +2016-04-20: +- Remove unused macros s, ff_poly, ff_hi, m1, m2, m3, FFmulX, + fwd_mcol, fwd_var, inv_var, si, so, fwd_rnd, inv_rnd, fwd_lrnd, + inv_lrnd, locals, l_copy, state_in, state_out, round, i_table, + li_table +- Remove unused arrays rijndael_enc_s_box, rijndael_enc_inv_s_box, + rijndael_enc_it_tab, rijndael_enc_il_tab + +2016-06-14: +- Added cast to make C++ compiler happy + +Files: glibc_common.h, my_file.h +Source: security section of MiBench + +2016-02-26: +- Merge into file rijndael_enc_libc.h + +File: rijndael_enc_libc.h + +2016-02-26: +- Replace size_x with unsigned long +- Remove defines LITTLE_ENDIAN and NULL +- Prefix all functions with "rijndael_enc" (instead of "my_") +- Prefix definitions that clash with the standard library with + "rijndael_enc" (instead of "my_") +- Applied code formatting with astyle as in the example + +Files: glibc_common.c, my_file.c +Source: security section of MiBench + +2016-02-26: +- Merge into file rijndael_enc_libc.c + +File: rijndael_enc_libc.c + +2016-02-26: +- Replace size_x with unsigned long +- Prefix all functions with "rijndael_enc" (instead of "my_") +- Prefix definitions that clash with the standard library with + "rijndael_enc" (instead of "my_") +- Applied code formatting with astyle as in the example + +File: input_small.c +Source: security section of MiBench + +2016-02-26: +- Break long lines diff --git a/all_pairs/source/rijndael_enc/aes.c b/all_pairs/source/rijndael_enc/aes.c new file mode 100644 index 0000000..c1282a7 --- /dev/null +++ b/all_pairs/source/rijndael_enc/aes.c @@ -0,0 +1,406 @@ +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of 128, + bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. +*/ + +#include "aes.h" + +#include "aestab.h" + +#define four_tables(x,tab,vf,rf,c) ( tab[0][bval(vf(x,0,c),rf(0,c))] ^ \ + tab[1][bval(vf(x,1,c),rf(1,c))] ^ \ + tab[2][bval(vf(x,2,c),rf(2,c))] ^ \ + tab[3][bval(vf(x,3,c),rf(3,c))] ) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((r-c)&3) + +#define ls_box(x,c) four_tables(x,rijndael_enc_fl_tab,vf1,rf2,c) + +#define inv_mcol(x) four_tables(x,rijndael_enc_im_tab,vf1,rf1,0) + +/* + Subroutine to set the block size (if variable) in bytes, legal + values being 16, 24 and 32. +*/ + +#define nc (Ncol) + +/* + Initialise the key schedule from the user supplied key. The key + length is now specified in bytes - 16, 24 or 32 as appropriate. + This corresponds to bit lengths of 128, 192 and 256 bits, and + to Nk values of 4, 6 and 8 respectively. +*/ + +#define mx(t,f) (*t++ = inv_mcol(*f),f++) +#define cp(t,f) *t++ = *f++ + +#define cpy(d,s) do { cp(d,s); cp(d,s); cp(d,s); cp(d,s); } while (0) +#define mix(d,s) do { mx(d,s); mx(d,s); mx(d,s); mx(d,s); } while (0) + +aes_ret rijndael_enc_set_key( byte in_key[], const word n_bytes, + const enum aes_key f, struct aes *cx ) +{ + word *kf, *kt, rci; + + if ( ( n_bytes & 7 ) || n_bytes < 16 || n_bytes > 32 || ( !( f & 1 ) && + !( f & 2 ) ) ) + return ( n_bytes ? cx->mode &= ~0x03, aes_bad : ( aes_ret )( cx->Nkey << 2 ) ); + + cx->mode = ( cx->mode & ~0x03 ) | ( ( byte )f & 0x03 ); + cx->Nkey = n_bytes >> 2; + cx->Nrnd = Nr( cx->Nkey, ( word )nc ); + + cx->e_key[0] = word_in( in_key ); + cx->e_key[1] = word_in( in_key + 4 ); + cx->e_key[2] = word_in( in_key + 8 ); + cx->e_key[3] = word_in( in_key + 12 ); + + kf = cx->e_key; + kt = kf + nc * ( cx->Nrnd + 1 ) - cx->Nkey; + rci = 0; + + switch ( cx->Nkey ) { + case 4: + _Pragma( "loopbound min 0 max 0" ) + do { + kf[4] = kf[0] ^ ls_box( kf[3], 3 ) ^ rijndael_enc_rcon_tab[rci++]; + kf[5] = kf[1] ^ kf[4]; + kf[6] = kf[2] ^ kf[5]; + kf[7] = kf[3] ^ kf[6]; + kf += 4; + } while ( kf < kt ); + break; + + case 6: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + _Pragma( "loopbound min 0 max 0" ) + do { + kf[ 6] = kf[0] ^ ls_box( kf[5], 3 ) ^ rijndael_enc_rcon_tab[rci++]; + kf[ 7] = kf[1] ^ kf[ 6]; + kf[ 8] = kf[2] ^ kf[ 7]; + kf[ 9] = kf[3] ^ kf[ 8]; + kf[10] = kf[4] ^ kf[ 9]; + kf[11] = kf[5] ^ kf[10]; + kf += 6; + } while ( kf < kt ); + break; + + case 8: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + cx->e_key[6] = word_in( in_key + 24 ); + cx->e_key[7] = word_in( in_key + 28 ); + _Pragma( "loopbound min 7 max 7" ) + do { + kf[ 8] = kf[0] ^ ls_box( kf[7], 3 ) ^ rijndael_enc_rcon_tab[rci++]; + kf[ 9] = kf[1] ^ kf[ 8]; + kf[10] = kf[2] ^ kf[ 9]; + kf[11] = kf[3] ^ kf[10]; + kf[12] = kf[4] ^ ls_box( kf[11], 0 ); + kf[13] = kf[5] ^ kf[12]; + kf[14] = kf[6] ^ kf[13]; + kf[15] = kf[7] ^ kf[14]; + kf += 8; + } while ( kf < kt ); + break; + } + + if ( ( cx->mode & 3 ) != enc ) { + word i; + + kt = cx->d_key + nc * cx->Nrnd; + kf = cx->e_key; + + cpy( kt, kf ); + kt -= 2 * nc; + + _Pragma( "loopbound min 0 max 0" ) + for ( i = 1; i < cx->Nrnd; ++i ) { + mix( kt, kf ); + kt -= 2 * nc; + } + + cpy( kt, kf ); + } + + return aes_good; +} + +short rijndael_enc_encrypt( unsigned char in_blk[], unsigned char out_blk[], + const struct aes *cx ) +{ + const unsigned long *kp = cx->e_key; + if ( !( cx->mode & 1 ) ) + return 0; + unsigned long b0[4]; + b0[0] = *( unsigned long * )in_blk ^ kp[0]; + b0[1] = *( unsigned long * )( in_blk + 4 )^kp[1]; + b0[2] = *( unsigned long * )( in_blk + 8 )^kp[2]; + b0[3] = *( unsigned long * )( in_blk + 12 )^kp[3]; + kp += 4; + unsigned long b1[4]; + switch ( cx->Nrnd ) { + case 14: + b1[0] = kp[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + kp += 8; + case 12: + b1[0] = kp[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + kp += 8; + case 10: + b1[0] = kp[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 8 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 8 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 8 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 8 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 12 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 12 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 12 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 12 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 16 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 16 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 16 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 16 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 20 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 20 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 20 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 20 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 24 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 24 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 24 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 24 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 28 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 28 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 28 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 28 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 32 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 32 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 32 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 32 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 36 )[0] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 36 )[1] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 36 )[2] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 36 )[3] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + } + *( unsigned long * )out_blk = ( b0[0] ); + *( unsigned long * )( out_blk + 4 ) = ( b0[1] ); + *( unsigned long * )( out_blk + 8 ) = ( b0[2] ); + *( unsigned long * )( out_blk + 12 ) = ( b0[3] ); + return aes_good; +} + diff --git a/all_pairs/source/rijndael_enc/aes.h b/all_pairs/source/rijndael_enc/aes.h new file mode 100644 index 0000000..908f95f --- /dev/null +++ b/all_pairs/source/rijndael_enc/aes.h @@ -0,0 +1,165 @@ +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + 1. FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of + 128 bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. + + 2. THE CIPHER INTERFACE + + byte (an unsigned 8-bit type) + word (an unsigned 32-bit type) + aes_ret: (a signed 16 bit type for function return values) + aes_good (value != 0, a good return) + aes_bad (value == 0, an error return) + enum aes_key: (encryption direction) + enc (set key for encryption) + dec (set key for decryption) + both (set key for both) + class or struct aes (structure for context) + + C subroutine calls: + + aes_ret set_blk(const word block_length, aes *cx) (variable block size) + aes_ret set_key(const byte key[], const word key_length, + const enum aes_key direction, aes *cx) + aes_ret encrypt(const byte input_blk[], byte output_blk[], const aes *cx) + aes_ret decrypt(const byte input_blk[], byte output_blk[], const aes *cx) + + IMPORTANT NOTE: If you are using this C interface and your compiler does + not set the memory used for objects to zero before use, you will need to + ensure that cx.mode is set to zero before using the C subroutine calls. + + The block length inputs to set_block and set_key are in numbers of + BYTES, not bits. The calls to subroutines must be made in the above + order but multiple calls can be made without repeating earlier calls + if their parameters have not changed. If the cipher block length is + variable but set_blk has not been called before cipher operations a + value of 16 is assumed (that is, the AES block size). In contrast to + earlier versions the block and key length parameters are now checked + for correctness and the encryption and decryption routines check to + ensure that an appropriate key has been set before they are called. + +*/ + +#ifndef _AES_H +#define _AES_H + +/* The only supported block size for the benchmark is 16 */ +#define BLOCK_SIZE 16 + +/* + The number of key schedule words for different block and key lengths + (allowing for the method of computation which requires the length to + be a multiple of the key length): + + Key Schedule key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 44 60 54 56 64 + length 20 | 60 60 66 70 80 + (bytes) 24 | 80 80 78 84 96 + 28 | 100 100 102 98 112 + 32 | 120 120 120 126 120 + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + The following values assume that the key length will be variable and may + be of maximum length (32 bytes). + + Nk = number_of_key_bytes / 4 + Nc = number_of_columns_in_state / 4 + Nr = number of encryption/decryption rounds + Rc = number of elements in rcon table + Ks = number of 32-bit words in key schedule +*/ + +#define Nr(Nk,Nc) ((Nk > Nc ? Nk : Nc) + 6) +#define Rc(Nk,Nc) ((Nb * (Nr(Nk,Nc) + 1) - 1) / Nk) +#define Ks(Nk,Nc) (Nk * (Rc(Nk,Nc) + 1)) + +#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11) +#define KS_LENGTH 4 * BLOCK_SIZE + +/* End of configuration options, but see also aes.c */ + +typedef unsigned char byte; /* must be an 8-bit storage unit */ +typedef unsigned long word; /* must be a 32-bit storage unit */ +typedef short aes_ret; /* function return value */ + +#define aes_bad 0 +#define aes_good 1 + +/* + upr(x,n): rotates bytes within words by n positions, moving bytes + to higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word +*/ + +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) +#define ups(x,n) ((x) << 8 * (n)) +#define bval(x,n) ((byte)((x) >> 8 * (n))) +#define byte_swap(x) (upr(x,1) & 0x00ff00ff | upr(x,3) & 0xff00ff00) +#define bytes2word(b0, b1, b2, b3) ((word)(b3) << 24 | (word)(b2) << 16 | \ + (word)(b1) << 8 | (b0)) + +#define word_in(x) *(word*)(x) +#define word_out(x,v) *(word*)(x) = (v) + +enum aes_const { Nrow = 4, /* the number of rows in the cipher state */ + Mcol = 8, /* maximum number of columns in the state */ + Ncol = BLOCK_SIZE / 4, + Shr0 = 0, /* the cyclic shift values for rows 0, 1, 2 & 3 */ + Shr1 = 1, + Shr2 = BLOCK_SIZE == 32 ? 3 : 2, + Shr3 = BLOCK_SIZE == 32 ? 4 : 3 + }; + +enum aes_key { enc = 1, /* set if encryption is needed */ + dec = 2, /* set if decryption is needed */ + both = 3 /* set if both are needed */ + }; + +struct aes { + word Nkey; /* the number of words in the key input block */ + word Nrnd; /* the number of cipher rounds */ + word e_key[KS_LENGTH]; /* the encryption key schedule */ + word d_key[KS_LENGTH]; /* the decryption key schedule */ + byte mode; /* encrypt, decrypt or both */ +}; + +aes_ret rijndael_enc_set_key( byte key[], const word n_bytes, + const enum aes_key f, struct aes *cx ); +aes_ret rijndael_enc_encrypt( byte in_blk[], byte out_blk[], + const struct aes *cx ); + +#endif diff --git a/all_pairs/source/rijndael_enc/aestab.h b/all_pairs/source/rijndael_enc/aestab.h new file mode 100644 index 0000000..9d347bc --- /dev/null +++ b/all_pairs/source/rijndael_enc/aestab.h @@ -0,0 +1,261 @@ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +/* + Used to ensure table is generated in the right format + depending on the internal byte order required. +*/ + +#define w0(p) 0x000000##p + +/* + Number of elements required in this table for different + block and key lengths is: + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + this table can be a table of bytes if the key schedule + code is adjusted accordingly +*/ + +const word rijndael_enc_rcon_tab[29] = { + w0( 01 ), w0( 02 ), w0( 04 ), w0( 08 ), + w0( 10 ), w0( 20 ), w0( 40 ), w0( 80 ), + w0( 1b ), w0( 36 ), w0( 6c ), w0( d8 ), + w0( ab ), w0( 4d ), w0( 9a ), w0( 2f ), + w0( 5e ), w0( bc ), w0( 63 ), w0( c6 ), + w0( 97 ), w0( 35 ), w0( 6a ), w0( d4 ), + w0( b3 ), w0( 7d ), w0( fa ), w0( ef ), + w0( c5 ) +}; + +#undef w0 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +#define r0(p,q,r,s) 0x##p##q##r##s +#define r1(p,q,r,s) 0x##q##r##s##p +#define r2(p,q,r,s) 0x##r##s##p##q +#define r3(p,q,r,s) 0x##s##p##q##r +#define w0(p) 0x000000##p +#define w1(p) 0x0000##p##00 +#define w2(p) 0x00##p##0000 +#define w3(p) 0x##p##000000 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +/* data for forward tables (other than last round) */ + +#define f_table \ + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6), \ + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91), \ + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56), \ + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec), \ + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa), \ + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb), \ + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45), \ + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b), \ + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c), \ + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83), \ + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9), \ + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a), \ + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d), \ + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f), \ + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df), \ + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea), \ + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34), \ + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b), \ + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d), \ + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13), \ + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1), \ + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6), \ + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72), \ + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85), \ + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed), \ + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11), \ + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe), \ + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b), \ + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05), \ + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1), \ + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42), \ + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf), \ + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3), \ + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e), \ + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a), \ + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6), \ + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3), \ + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b), \ + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28), \ + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad), \ + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14), \ + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8), \ + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4), \ + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2), \ + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da), \ + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49), \ + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf), \ + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10), \ + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c), \ + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97), \ + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e), \ + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f), \ + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc), \ + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c), \ + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69), \ + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27), \ + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22), \ + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33), \ + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9), \ + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5), \ + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a), \ + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0), \ + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e), \ + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) + +/* generate the required tables in the desired endian format */ + +#undef r +#define r r0 + +const word rijndael_enc_ft_tab[4][256] = { + { f_table }, +#undef r +#define r r1 + { f_table }, +#undef r +#define r r2 + { f_table }, +#undef r +#define r r3 + { f_table } +}; + +/* generate the required tables in the desired endian format */ + +#undef r +#define r(p,q,r,s) w0(q) +const word rijndael_enc_fl_tab[4][256] = { + { f_table }, +#undef r +#define r(p,q,r,s) w1(q) + { f_table }, +#undef r +#define r(p,q,r,s) w2(q) + { f_table }, +#undef r +#define r(p,q,r,s) w3(q) + { f_table } +}; + +#define m_table \ + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12), \ + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a), \ + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62), \ + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a), \ + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2), \ + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca), \ + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82), \ + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba), \ + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9), \ + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1), \ + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9), \ + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81), \ + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29), \ + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11), \ + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59), \ + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61), \ + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf), \ + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87), \ + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf), \ + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7), \ + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f), \ + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67), \ + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f), \ + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17), \ + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64), \ + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c), \ + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14), \ + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c), \ + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84), \ + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc), \ + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4), \ + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc), \ + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53), \ + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b), \ + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23), \ + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b), \ + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3), \ + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b), \ + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3), \ + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb), \ + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88), \ + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0), \ + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8), \ + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0), \ + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68), \ + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50), \ + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18), \ + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20), \ + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe), \ + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6), \ + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e), \ + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6), \ + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e), \ + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26), \ + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e), \ + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56), \ + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25), \ + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d), \ + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55), \ + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d), \ + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5), \ + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd), \ + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5), \ + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d) + +#undef r +#define r r0 + +const word rijndael_enc_im_tab[4][256] = { + { m_table }, +#undef r +#define r r1 + { m_table }, +#undef r +#define r r2 + { m_table }, +#undef r +#define r r3 + { m_table } +}; diff --git a/all_pairs/source/rijndael_enc/input_small.c b/all_pairs/source/rijndael_enc/input_small.c new file mode 100644 index 0000000..b3eee55 --- /dev/null +++ b/all_pairs/source/rijndael_enc/input_small.c @@ -0,0 +1,1963 @@ +unsigned char rijndael_enc_data[] = { + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','t','s','C','o', + 'm','m','e','n','c','e','m','e','n','t','A','d','d','r','e','s', + 's','a','t','M','I','T','L','a','d','i','e','s','a','n','d','g', + 'e','n','t','l','e','m','e','n','o','f','t','h','e','c','l','a', + 's','s','o','f','9','7','W','e','a','r','s','u','n','s','c','r', + 'e','e','n','I','f','I','c','o','u','l','d','o','f','f','e','r', + 'y','o','u','o','n','l','y','o','n','e','t','i','p','f','o','r', + 't','h','e','f','u','t','u','r','e','s','u','n','s','c','r','e', + 'e','n','w','o','u','l','d','b','e','i','t','T','h','e','l','o', + 'n','g','t','e','r','m','b','e','n','e','f','i','t','s','o','f', + 's','u','n','s','c','r','e','e','n','h','a','v','e','b','e','e', + 'n','p','r','o','v','e','d','b','y','s','c','i','e','n','t','i', + 's','t','s','w','h','e','r','e','a','s','t','h','e','r','e','s', + 't','o','f','m','y','a','d','v','i','c','e','h','a','s','n','o', + 'b','a','s','i','s','m','o','r','e','r','e','l','i','a','b','l', + 'e','t','h','a','n','m','y','o','w','n','m','e','a','n','d','e', + 'r','i','n','g','e','x','p','e','r','i','e','n','c','e','I','w', + 'i','l','l','d','i','s','p','e','n','s','e','t','h','i','s','a', + 'd','v','i','c','e','n','o','w','E','n','j','o','y','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','O','h','n','e','v','e','r', + 'm','i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n', + 'd','e','r','s','t','a','n','d','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','u','n','t','i','l','t','h','e','y','v','e','f', + 'a','d','e','d','B','u','t','t','r','u','s','t','m','e','i','n', + '2','0','y','e','a','r','s','y','o','u','l','l','l','o','o','k', + 'b','a','c','k','a','t','p','h','o','t','o','s','o','f','y','o', + 'u','r','s','e','l','f','a','n','d','r','e','c','a','l','l','i', + 'n','a','w','a','y','y','o','u','c','a','n','t','g','r','a','s', + 'p','n','o','w','h','o','w','m','u','c','h','p','o','s','s','i', + 'b','i','l','i','t','y','l','a','y','b','e','f','o','r','e','y', + 'o','u','a','n','d','h','o','w','f','a','b','u','l','o','u','s', + 'y','o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y', + 'o','u','a','r','e','n','o','t','a','s','f','a','t','a','s','y', + 'o','u','i','m','a','g','i','n','e','D','o','n','t','w','o','r', + 'r','y','a','b','o','u','t','t','h','e','f','u','t','u','r','e', + 'O','r','w','o','r','r','y','b','u','t','k','n','o','w','t','h', + 'a','t','K','u','r','t','V','o','n','n','e','g','u','t','s','C', + 'o','m','m','e','n','c','e','m','e','n','t','A','d','d','r','e', + 's','s','a','t','M','I','T','L','a','d','i','e','s','a','n','d', + 'g','e','n','t','l','e','m','e','n','o','f','t','h','e','c','l', + 'a','s','s','o','f','9','7','W','e','a','r','s','u','n','s','c', + 'r','e','e','n','I','f','I','c','o','u','l','d','o','f','f','e', + 'r','y','o','u','o','n','l','y','o','n','e','t','i','p','f','o', + 'r','t','h','e','f','u','t','u','r','e','s','u','n','s','c','r', + 'e','e','n','w','o','u','l','d','b','e','i','t','T','h','e','l', + 'o','n','g','t','e','r','m','b','e','n','e','f','i','t','s','o', + 'f','s','u','n','s','c','r','e','e','n','h','a','v','e','b','e', + 'e','n','p','r','o','v','e','d','b','y','s','c','i','e','n','t', + 'i','s','t','s','w','h','e','r','e','a','s','t','h','e','r','e', + 's','t','o','f','m','y','a','d','v','i','c','e','h','a','s','n', + 'o','b','a','s','i','s','m','o','r','e','r','e','l','i','a','b', + 'l','e','t','h','a','n','m','y','o','w','n','m','e','a','n','d', + 'e','r','i','n','g','e','x','p','e','r','i','e','n','c','e','I', + 'w','i','l','l','d','i','s','p','e','n','s','e','t','h','i','s', + 'a','d','v','i','c','e','n','o','w','E','n','j','o','y','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','O','h','n','e','v','e', + 'r','m','i','n','d','Y','o','u','w','i','l','l','n','o','t','u', + 'n','d','e','r','s','t','a','n','d','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','u','n','t','i','l','t','h','e','y','v','e', + 'f','a','d','e','d','B','u','t','t','r','u','s','t','m','e','i', + 'n','2','0','y','e','a','r','s','y','o','u','l','l','l','o','o', + 'k','b','a','c','k','a','t','p','h','o','t','o','s','o','f','y', + 'o','u','r','s','e','l','f','a','n','d','r','e','c','a','l','l', + 'i','n','a','w','a','y','y','o','u','c','a','n','t','g','r','a', + 's','p','n','o','w','h','o','w','m','u','c','h','p','o','s','s', + 'i','b','i','l','i','t','y','l','a','y','b','e','f','o','r','e', + 'y','o','u','a','n','d','h','o','w','f','a','b','u','l','o','u', + 's','y','o','u','r','e','a','l','l','y','l','o','o','k','e','d', + 'Y','o','u','a','r','e','n','o','t','a','s','f','a','t','a','s', + 'y','o','u','i','m','a','g','i','n','e','D','o','n','t','w','o', + 'r','r','y','a','b','o','u','t','t','h','e','f','u','t','u','r', + 'e','O','r','w','o','r','r','y','b','u','t','k','n','o','w','t', + 'h','a','t','t','s','C','o','m','m','e','n','c','e','m','e','n', + 't','A','d','d','r','e','s','s','a','t','M','I','T','L','a','d', + 'i','e','s','a','n','d','g','e','n','t','l','e','m','e','n','o', + 'f','t','h','e','c','l','a','s','s','o','f','9','7','W','e','a', + 'r','s','u','n','s','c','r','e','e','n','I','f','I','c','o','u', + 'l','d','o','f','f','e','r','y','o','u','o','n','l','y','o','n', + 'e','t','i','p','f','o','r','t','h','e','f','u','t','u','r','e', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','t','s','C','o', + 'm','m','e','n','c','e','m','e','n','t','A','d','d','r','e','s', + 's','a','t','M','I','T','L','a','d','i','e','s','a','n','d','g', + 'e','n','t','l','e','m','e','n','o','f','t','h','e','c','l','a', + 's','s','o','f','9','7','W','e','a','r','s','u','n','s','c','r', + 'e','e','n','I','f','I','c','o','u','l','d','o','f','f','e','r', + 'y','o','u','o','n','l','y','o','n','e','t','i','p','f','o','r', + 't','h','e','f','u','t','u','r','e','s','u','n','s','c','r','e', + 'e','n','w','o','u','l','d','b','e','i','t','T','h','e','l','o', + 'n','g','t','e','r','m','b','e','n','e','f','i','t','s','o','f', + 's','u','n','s','c','r','e','e','n','h','a','v','e','b','e','e', + 'n','p','r','o','v','e','d','b','y','s','c','i','e','n','t','i', + 's','t','s','w','h','e','r','e','a','s','t','h','e','r','e','s', + 't','o','f','m','y','a','d','v','i','c','e','h','a','s','n','o', + 'b','a','s','i','s','m','o','r','e','r','e','l','i','a','b','l', + 'e','t','h','a','n','m','y','o','w','n','m','e','a','n','d','e', + 'r','i','n','g','e','x','p','e','r','i','e','n','c','e','I','w', + 'i','l','l','d','i','s','p','e','n','s','e','t','h','i','s','a', + 'd','v','i','c','e','n','o','w','E','n','j','o','y','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','O','h','n','e','v','e','r', + 'm','i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n', + 'd','e','r','s','t','a','n','d','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','u','n','t','i','l','t','h','e','y','v','e','f', + 'a','d','e','d','B','u','t','t','r','u','s','t','m','e','i','n', + '2','0','y','e','a','r','s','y','o','u','l','l','l','o','o','k', + 'b','a','c','k','a','t','p','h','o','t','o','s','o','f','y','o', + 'u','r','s','e','l','f','a','n','d','r','e','c','a','l','l','i', + 'n','a','w','a','y','y','o','u','c','a','n','t','g','r','a','s', + 'p','n','o','w','h','o','w','m','u','c','h','p','o','s','s','i', + 'b','i','l','i','t','y','l','a','y','b','e','f','o','r','e','y', + 'o','u','a','n','d','h','o','w','f','a','b','u','l','o','u','s', + 'y','o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y', + 'o','u','a','r','e','n','o','t','a','s','f','a','t','a','s','y', + 'o','u','i','m','a','g','i','n','e','D','o','n','t','w','o','r', + 'r','y','a','b','o','u','t','t','h','e','f','u','t','u','r','e', + 'O','r','w','o','r','r','y','b','u','t','k','n','o','w','t','h', + 'a','t','K','u','r','t','V','o','n','n','e','g','u','t','s','C', + 'o','m','m','e','n','c','e','m','e','n','t','A','d','d','r','e', + 's','s','a','t','M','I','T','L','a','d','i','e','s','a','n','d', + 'g','e','n','t','l','e','m','e','n','o','f','t','h','e','c','l', + 'a','s','s','o','f','9','7','W','e','a','r','s','u','n','s','c', + 'r','e','e','n','I','f','I','c','o','u','l','d','o','f','f','e', + 'r','y','o','u','o','n','l','y','o','n','e','t','i','p','f','o', + 'r','t','h','e','f','u','t','u','r','e','s','u','n','s','c','r', + 'e','e','n','w','o','u','l','d','b','e','i','t','T','h','e','l', + 'o','n','g','t','e','r','m','b','e','n','e','f','i','t','s','o', + 'f','s','u','n','s','c','r','e','e','n','h','a','v','e','b','e', + 'e','n','p','r','o','v','e','d','b','y','s','c','i','e','n','t', + 'i','s','t','s','w','h','e','r','e','a','s','t','h','e','r','e', + 's','t','o','f','m','y','a','d','v','i','c','e','h','a','s','n', + 'o','b','a','s','i','s','m','o','r','e','r','e','l','i','a','b', + 'l','e','t','h','a','n','m','y','o','w','n','m','e','a','n','d', + 'e','r','i','n','g','e','x','p','e','r','i','e','n','c','e','I', + 'w','i','l','l','d','i','s','p','e','n','s','e','t','h','i','s', + 'a','d','v','i','c','e','n','o','w','E','n','j','o','y','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','O','h','n','e','v','e', + 'r','m','i','n','d','Y','o','u','w','i','l','l','n','o','t','u', + 'n','d','e','r','s','t','a','n','d','t','h','e','p','o','w','e', + 'r','a','K','u','r','t','V','o','n','n','e','g','u','t','s','C', + 'o','m','m','e','n','c','e','m','e','n','t','A','d','d','r','e', + 's','s','a','t','M','I','T','L','a','d','i','e','s','a','n','d', + 'g','e','n','t','l','e','m','e','n','o','f','t','h','e','c','l', + 'a','s','s','o','f','9','7','W','e','a','r','s','u','n','s','c', + 'r','e','e','n','I','f','I','c','o','u','l','d','o','f','f','e', + 'r','y','o','u','o','n','l','y','o','n','e','t','i','p','f','o', + 'r','t','h','e','f','u','t','u','r','e','s','u','n','s','c','r', + 'e','e','n','w','o','u','l','d','b','e','i','t','T','h','e','l', + 'o','n','g','t','e','r','m','b','e','n','e','f','i','t','s','o', + 'f','s','u','n','s','c','r','e','e','n','h','a','v','e','b','e', + 'e','n','p','r','o','v','e','d','b','y','s','c','i','e','n','t', + 'i','s','t','s','w','h','e','r','e','a','s','t','h','e','r','e', + 's','t','o','f','m','y','a','d','v','i','c','e','h','a','s','n', + 'o','b','a','s','i','s','m','o','r','e','r','e','l','i','a','b', + 'l','e','t','h','a','n','m','y','o','w','n','m','e','a','n','d', + 'e','r','i','n','g','e','x','p','e','r','i','e','n','c','e','I', + 'w','i','l','l','d','i','s','p','e','n','s','e','t','h','i','s', + 'a','d','v','i','c','e','n','o','w','E','n','j','o','y','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','O','h','n','e','v','e', + 'r','m','i','n','d','Y','o','u','w','i','l','l','n','o','t','u', + 'n','d','e','r','s','t','a','n','d','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','u','n','t','i','l','t','h','e','y','v','e', + 'f','a','d','e','d','B','u','t','t','r','u','s','t','m','e','i', + 'n','2','0','y','e','a','r','s','y','o','u','l','l','l','o','o', + 'k','b','a','c','k','a','t','p','h','o','t','o','s','o','f','y', + 'o','u','r','s','e','l','f','a','n','d','r','e','c','a','l','l', + 'i','n','a','w','a','y','y','o','u','c','a','n','t','g','r','a', + 's','p','n','o','w','h','o','w','m','u','c','h','p','o','s','s', + 'i','b','i','l','i','t','y','l','a','y','b','e','f','o','r','e', + 'y','o','u','a','n','d','h','o','w','f','a','b','u','l','o','u', + 's','y','o','u','r','e','a','l','l','y','l','o','o','k','e','d', + 'Y','o','u','a','r','e','n','o','t','a','s','f','a','t','a','s', + 'y','o','u','i','m','a','g','i','n','e','D','o','n','t','w','o', + 'r','r','y','a','b','o','u','t','t','h','e','f','u','t','u','r', + 'e','O','r','w','o','r','r','y','b','u','t','k','n','o','w','t', + 'h','a','t','K','u','r','t','V','o','n','n','e','g','u','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','K', + 'u','r','t','V','o','n','n','e','g','u','t','s','C','o','m','m', + 'e','n','c','e','m','e','n','t','A','d','d','r','e','s','s','a', + 't','M','I','T','L','a','d','i','e','s','a','n','d','g','e','n', + 't','l','e','m','e','n','o','f','t','h','e','c','l','a','s','s', + 'o','f','9','7','W','e','a','r','s','u','n','s','c','r','e','e', + 'n','I','f','I','c','o','u','l','d','o','f','f','e','r','y','o', + 'u','o','n','l','y','o','n','e','t','i','p','f','o','r','t','h', + 'e','f','u','t','u','r','e','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','K', + 'u','r','t','V','o','n','n','e','g','u','t','s','C','o','m','m', + 'e','n','c','e','m','e','n','t','A','d','d','r','e','s','s','a', + 't','M','I','T','L','a','d','i','e','s','a','n','d','g','e','n', + 't','l','e','m','e','n','o','f','t','h','e','c','l','a','s','s', + 'o','f','9','7','W','e','a','r','s','u','n','s','c','r','e','e', + 'n','I','f','I','c','o','u','l','d','o','f','f','e','r','y','o', + 'u','o','n','l','y','o','n','e','t','i','p','f','o','r','t','h', + 'e','f','u','t','u','r','e','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','n','d','b','e','a','u','t','y', + 'o','f','y','o','u','r','y','o','u','t','h','u','n','t','i','l', + 't','h','e','y','v','e','f','a','d','e','d','B','u','t','t','r', + 'u','s','t','m','e','i','n','2','0','y','e','a','r','s','y','o', + 'u','l','l','l','o','o','k','b','a','c','k','a','t','p','h','o', + 't','o','s','o','f','y','o','u','r','s','e','l','f','a','n','d', + 'r','e','c','a','l','l','i','n','a','w','a','y','y','o','u','c', + 'a','n','t','g','r','a','s','p','n','o','w','h','o','w','m','u', + 'c','h','p','o','s','s','i','b','i','l','i','t','y','l','a','y', + 'b','e','f','o','r','e','y','o','u','a','n','d','h','o','w','f', + 'a','b','u','l','o','u','s','y','o','u','r','e','a','l','l','y', + 'l','o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a', + 's','f','a','t','a','s','y','o','u','i','m','a','g','i','n','e', + 'D','o','n','t','w','o','r','r','y','a','b','o','u','t','t','h', + 'e','f','u','t','u','r','e','O','r','w','o','r','r','y','b','u', + 't','k','n','o','w','t','h','a','t','s','u','n','s','c','r','e', + 'e','n','w','o','u','l','d','b','e','i','t','T','h','e','l','o', + 'n','g','t','e','r','m','b','e','n','e','f','i','t','s','o','f', + 's','u','n','s','c','r','e','e','n','h','a','v','e','b','e','e', + 'n','p','r','o','v','e','d','b','y','s','c','i','e','n','t','i', + 's','t','s','w','h','e','r','e','a','s','t','h','e','r','e','s', + 't','o','f','m','y','a','d','v','i','c','e','h','a','s','n','o', + 'b','a','s','i','s','m','o','r','e','r','e','l','i','a','b','l', + 'e','t','h','a','n','m','y','o','w','n','m','e','a','n','d','e', + 'r','i','n','g','e','x','p','e','r','i','e','n','c','e','I','w', + 'i','l','l','d','i','s','p','e','n','s','e','t','h','i','s','a', + 'd','v','i','c','e','n','o','w','E','n','j','o','y','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','O','h','n','e','v','e','r', + 'm','i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n', + 'd','e','r','s','t','a','n','d','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','u','n','t','i','l','t','h','e','y','v','e','f', + 'a','d','e','d','B','u','t','t','r','u','s','t','m','e','i','n', + '2','0','y','e','a','r','s','y','o','u','l','l','l','o','o','k', + 'b','a','c','k','a','t','p','h','o','t','o','s','o','f','y','o', + 'u','r','s','e','l','f','a','n','d','r','e','c','a','l','l','i', + 'n','a','w','a','y','y','o','u','c','a','n','t','g','r','a','s', + 'p','n','o','w','h','o','w','m','u','c','h','p','o','s','s','i', + 'b','i','l','i','t','y','l','a','y','b','e','f','o','r','e','y', + 'o','u','a','n','d','h','o','w','f','a','b','u','l','o','u','s', + 'y','o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y', + 'o','u','a','r','e','n','o','t','a','s','f','a','t','a','s','y', + 'o','u','i','m','a','g','i','n','e','D','o','n','t','w','o','r', + 'r','y','a','b','o','u','t','t','h','e','f','u','t','u','r','e', + 'O','r','w','o','r','r','y','b','u','t','k','n','o','w','t','h', + 'a','t','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','u','n','t','i','l','t','h','e','y','v','e', + 'f','a','d','e','d','B','u','t','t','r','u','s','t','m','e','i', + 'n','2','0','y','e','a','r','s','y','o','u','l','l','l','o','o', + 'k','b','a','c','k','a','t','p','h','o','t','o','s','o','f','y', + 'o','u','r','s','e','l','f','a','n','d','r','e','c','a','l','l', + 'i','n','a','w','a','y','y','o','u','c','a','n','t','g','r','a', + 's','p','n','o','w','h','o','w','m','u','c','h','p','o','s','s', + 'i','b','i','l','i','t','y','l','a','y','b','e','f','o','r','e', + 'y','o','u','a','n','d','h','o','w','f','a','b','u','l','o','u', + 's','y','o','u','r','e','a','l','l','y','l','o','o','k','e','d', + 'Y','o','u','a','r','e','n','o','t','a','s','f','a','t','a','s', + 'y','o','u','i','m','a','g','i','n','e','D','o','n','t','w','o', + 'r','r','y','a','b','o','u','t','t','h','e','f','u','t','u','r', + 'e','O','r','w','o','r','r','y','b','u','t','k','n','o','w','t', + 'h','a','t','s','u','n','s','c','r','e','e','n','w','o','u','l', + 'd','b','e','i','t','T','h','e','l','o','n','g','t','e','r','m', + 'b','e','n','e','f','i','t','s','o','f','s','u','n','s','c','r', + 'e','e','n','h','a','v','e','b','e','e','n','p','r','o','v','e', + 'd','b','y','s','c','i','e','n','t','i','s','t','s','w','h','e', + 'r','e','a','s','t','h','e','r','e','s','t','o','f','m','y','a', + 'd','v','i','c','e','h','a','s','n','o','b','a','s','i','s','m', + 'o','r','e','r','e','l','i','a','b','l','e','t','h','a','n','m', + 'y','o','w','n','m','e','a','n','d','e','r','i','n','g','e','x', + 'p','e','r','i','e','n','c','e','I','w','i','l','l','d','i','s', + 'p','e','n','s','e','t','h','i','s','a','d','v','i','c','e','n', + 'o','w','E','n','j','o','y','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y','o', + 'u','w','i','l','l','n','o','t','u','n','d','e','r','s','t','a', + 'n','d','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','u','n', + 't','i','l','t','h','e','y','v','e','f','a','d','e','d','B','u', + 't','t','r','u','s','t','m','e','i','n','2','0','y','e','a','r', + 's','y','o','u','l','l','l','o','o','k','b','a','c','k','a','t', + 'p','h','o','t','o','s','o','f','y','o','u','r','s','e','l','f', + 'a','n','d','r','e','c','a','l','l','i','n','a','w','a','y','y', + 'o','u','c','a','n','t','g','r','a','s','p','n','o','w','h','o', + 'w','m','u','c','h','p','o','s','s','i','b','i','l','i','t','y', + 'l','a','y','b','e','f','o','r','e','y','o','u','a','n','d','h', + 'o','w','f','a','b','u','l','o','u','s','y','o','u','r','e','a', + 'l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e','n', + 'o','t','a','s','f','a','t','a','s','y','o','u','i','m','a','g', + 'i','n','e','D','o','n','t','w','o','r','r','y','a','b','o','u', + 't','t','h','e','f','u','t','u','r','e','O','r','w','o','r','r', + 'y','b','u','t','k','n','o','w','t','h','a','t','b','u','t','k', + 'n','o','w','t','h','a','t','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 't','s','C','o','m','m','e','n','c','e','m','e','n','t','A','d', + 'd','r','e','s','s','a','t','M','I','T','L','a','d','i','e','s', + 'a','n','d','g','e','n','t','l','e','m','e','n','o','f','t','h', + 'e','c','l','a','s','s','o','f','9','7','W','e','a','r','s','u', + 'n','s','c','r','e','e','n','I','f','I','c','o','u','l','d','o', + 'f','f','e','r','y','o','u','o','n','l','y','o','n','e','t','i', + 'p','f','o','r','t','h','e','f','u','t','u','r','e','s','u','n', + 's','c','r','e','e','n','w','o','u','l','d','b','e','i','t','T', + 'h','e','l','o','n','g','t','e','r','m','b','e','n','e','f','i', + 't','s','o','f','s','u','n','s','c','r','e','e','n','h','a','v', + 'e','b','e','e','n','p','r','o','v','e','d','b','y','s','c','i', + 'e','n','t','i','s','t','s','w','h','e','r','e','a','s','t','h', + 'e','r','e','s','t','o','f','m','y','a','d','v','i','c','e','h', + 'a','s','n','o','b','a','s','i','s','m','o','r','e','r','e','l', + 'i','a','b','l','e','t','h','a','n','m','y','o','w','n','m','e', + 'a','n','d','e','r','i','n','g','e','x','p','e','r','i','e','n', + 'c','e','I','w','i','l','l','d','i','s','p','e','n','s','e','t', + 'h','i','s','a','d','v','i','c','e','n','o','w','E','n','j','o', + 'y','t','h','e','p','o','w','e','r','a','n','d','b','e','a','u', + 't','y','o','f','y','o','u','r','y','o','u','t','h','O','h','n', + 'e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n', + 'o','t','u','n','d','e','r','s','t','a','n','d','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','u','n','t','i','l','t','h','e', + 'y','v','e','f','a','d','e','d','B','u','t','t','r','u','s','t', + 'm','e','i','n','2','0','y','e','a','r','s','y','o','u','l','l', + 'l','o','o','k','b','a','c','k','a','t','p','h','o','t','o','s', + 'o','f','y','o','u','r','s','e','l','f','a','n','d','r','e','c', + 'a','l','l','i','n','a','w','a','y','y','o','u','c','a','n','t', + 'g','r','a','s','p','n','o','w','h','o','w','m','u','c','h','p', + 'o','s','s','i','b','i','l','i','t','y','l','a','y','b','e','f', + 'o','r','e','y','o','u','a','n','d','h','o','w','f','a','b','u', + 'l','o','u','s','y','o','u','r','e','a','l','l','y','l','o','o', + 'k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a', + 't','a','s','y','o','u','i','m','a','g','i','n','e','D','o','n', + 't','w','o','r','r','y','a','b','o','u','t','t','h','e','f','u', + 't','u','r','e','O','r','w','o','r','r','y','b','u','t','k','n', + 'o','w','t','h','a','t','K','u','r','t','V','o','n','n','e','g', + 'u','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','s','u', + 'n','s','c','r','e','e','n','w','o','u','l','d','b','e','i','t', + 'T','h','e','l','o','n','g','t','e','r','m','b','e','n','e','f', + 'i','t','s','o','f','s','u','n','s','c','r','e','e','n','h','a', + 'v','e','b','e','e','n','p','r','o','v','e','d','b','y','s','c', + 'i','e','n','t','i','s','t','s','w','h','e','r','e','a','s','t', + 'h','e','r','e','s','t','o','f','m','y','a','d','v','i','c','e', + 'h','a','s','n','o','b','a','s','i','s','m','o','r','e','r','e', + 'l','i','a','b','l','e','t','h','a','n','m','y','o','w','n','m', + 'e','a','n','d','e','r','i','n','g','e','x','p','e','r','i','e', + 'n','c','e','I','w','i','l','l','d','i','s','p','e','n','s','e', + 't','h','i','s','a','d','v','i','c','e','n','o','w','E','n','j', + 'o','y','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','O','h', + 'n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l', + 'n','o','t','u','n','d','e','r','s','t','a','n','d','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','u','n','t','i','l','t','h', + 'e','y','v','e','f','a','d','e','d','B','u','t','t','r','u','s', + 't','m','e','i','n','2','0','y','e','a','r','s','y','o','u','l', + 'l','l','o','o','k','b','a','c','k','a','t','p','h','o','t','o', + 's','o','f','y','o','u','r','s','e','l','f','a','n','d','r','e', + 'c','a','l','l','i','n','a','w','a','y','y','o','u','c','a','n', + 't','g','r','a','s','p','n','o','w','h','o','w','m','u','c','h', + 'p','o','s','s','i','b','i','l','i','t','y','l','a','y','b','e', + 'f','o','r','e','y','o','u','a','n','d','h','o','w','f','a','b', + 'u','l','o','u','s','y','o','u','r','e','a','l','l','y','l','o', + 'o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f', + 'a','t','a','s','y','o','u','i','m','a','g','i','n','e','D','o', + 'n','t','w','o','r','r','y','a','b','o','u','t','t','h','e','f', + 'u','t','u','r','e','O','r','w','o','r','r','y','b','u','t','k', + 'n','o','w','t','h','a','t','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + '\n', 'l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','\n', 'l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 't','s','C','o','m','m','e','n','c','e','m','e','n','t','A','d', + 'd','r','e','s','s','a','t','M','I','T','L','a','d','i','e','s', + 'a','n','d','g','e','n','t','l','e','m','e','n','o','f','t','h', + 'e','c','l','a','s','s','o','f','9','7','W','e','a','r','s','u', + 'n','s','c','r','e','e','n','I','f','I','c','o','u','l','d','o', + 'f','f','e','r','y','o','u','o','n','l','y','o','n','e','t','i', + 'p','f','o','r','t','h','e','f','u','t','u','r','e','s','u','n', + 's','c','r','e','e','n','w','o','u','l','d','b','e','i','t','T', + 'h','e','l','o','n','g','t','e','r','m','b','e','n','e','f','i', + 't','s','o','f','s','u','n','s','c','r','e','e','n','h','a','v', + 'e','b','e','e','n','p','r','o','v','e','d','b','y','s','c','i', + 'e','n','t','i','s','t','s','w','h','e','r','e','a','s','t','h', + 'e','r','e','s','t','o','f','m','y','a','d','v','i','c','e','h', + 'a','s','n','o','b','a','s','i','s','m','o','r','e','r','e','l', + 'i','a','b','l','e','t','h','a','n','m','y','o','w','n','m','e', + 'a','n','d','e','r','i','n','g','e','x','p','e','r','i','e','n', + 'c','e','I','w','i','l','l','d','i','s','p','e','n','s','e','t', + 'h','i','s','a','d','v','i','c','e','n','o','w','E','n','j','o', + 'y','t','h','e','p','o','w','e','r','a','n','d','b','e','a','u', + 't','y','o','f','y','o','u','r','y','o','u','t','h','O','h','n', + 'e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n', + 'o','t','u','n','d','e','r','s','t','a','n','d','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','u','n','t','i','l','t','h','e', + 'y','v','e','f','a','d','e','d','B','u','t','t','r','u','s','t', + 'm','e','i','n','2','0','y','e','a','r','s','y','o','u','l','l', + 'l','o','o','k','b','a','c','k','a','t','p','h','o','t','o','s', + 'o','f','y','o','u','r','s','e','l','f','a','n','d','r','e','c', + 'a','l','l','i','n','a','w','a','y','y','o','u','c','a','n','t', + 'g','r','a','s','p','n','o','w','h','o','w','m','u','c','h','p', + 'o','s','s','i','b','i','l','i','t','y','l','a','y','b','e','f', + 'o','r','e','y','o','u','a','n','d','h','o','w','f','a','b','u', + 'l','o','u','s','y','o','u','r','e','a','l','l','y','l','o','o', + 'k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a', + 't','a','s','y','o','u','i','m','a','g','i','n','e','D','o','n', + 't','w','o','r','r','y','a','b','o','u','t','t','h','e','f','u', + 't','u','r','e','O','r','w','o','r','r','y','b','u','t','k','n', + 'o','w','t','h','a','t','K','u','r','t','V','o','n','n','e','g', + 'u','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','s','u', + 'n','s','c','r','e','e','n','w','o','u','l','d','b','e','i','t', + 'T','h','e','l','o','n','g','t','e','r','m','b','e','n','e','f', + 'i','t','s','o','f','s','u','n','s','c','r','e','e','n','h','a', + 'v','e','b','e','e','n','p','r','o','v','e','d','b','y','s','c', + 'i','e','n','t','i','s','t','s','w','h','e','r','e','a','s','t', + 'h','e','r','e','s','t','o','f','m','y','a','d','v','i','c','e', + 'h','a','s','n','o','b','a','s','i','s','m','o','r','e','r','e', + 'l','i','a','b','l','e','t','h','a','n','m','y','o','w','n','m', + 'e','a','n','d','e','r','i','n','g','e','x','p','e','r','i','e', + 'n','c','e','I','w','i','l','l','d','i','s','p','e','n','s','e', + 't','h','i','s','a','d','v','i','c','e','n','o','w','E','n','j', + 'o','y','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','O','h', + 'n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l', + 'n','o','t','u','n','d','e','r','s','t','a','n','d','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','u','n','t','i','l','t','h', + 'e','y','v','e','f','a','d','e','d','B','u','t','t','r','u','s', + 't','m','e','i','n','2','0','y','e','a','r','s','y','o','u','l', + 'l','l','o','o','k','b','a','c','k','a','t','p','h','o','t','o', + 's','o','f','y','o','u','r','s','e','l','f','a','n','d','r','e', + 'c','a','l','l','i','n','a','w','a','y','y','o','u','c','a','n', + 't','g','r','a','s','p','n','o','w','h','o','w','m','u','c','h', + 'p','o','s','s','i','b','i','l','i','t','y','l','a','y','b','e', + 'f','o','r','e','y','o','u','a','n','d','h','o','w','f','a','b', + 'u','l','o','u','s','y','o','u','r','e','a','l','l','y','l','o', + 'o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f', + 'a','t','a','s','y','o','u','i','m','a','g','i','n','e','D','o', + 'n','t','w','o','r','r','y','a','b','o','u','t','t','h','e','f', + 'u','t','u','r','e','O','r','w','o','r','r','y','b','u','t','k', + 'n','o','w','t','h','a','t','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + '\n', 'l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','\n', 'l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 't','s','C','o','m','m','e','n','c','e','m','e','n','t','A','d', + 'd','r','e','s','s','a','t','M','I','T','L','a','d','i','e','s', + 'a','n','d','g','e','n','t','l','e','m','e','n','o','f','t','h', + 'e','c','l','a','s','s','o','f','9','7','W','e','a','r','s','u', + 'n','s','c','r','e','e','n','I','f','I','c','o','u','l','d','o', + 'f','f','e','r','y','o','u','o','n','l','y','o','n','e','t','i', + 'p','f','o','r','t','h','e','f','u','t','u','r','e','s','u','n', + 's','c','r','e','e','n','w','o','u','l','d','b','e','i','t','T', + 'h','e','l','o','n','g','t','e','r','m','b','e','n','e','f','i', + 't','s','o','f','s','u','n','s','c','r','e','e','n','h','a','v', + 'e','b','e','e','n','p','r','o','v','e','d','b','y','s','c','i', + 'e','n','t','i','s','t','s','w','h','e','r','e','a','s','t','h', + 'e','r','e','s','t','o','f','m','y','a','d','v','i','c','e','h', + 'a','s','n','o','b','a','s','i','s','m','o','r','e','r','e','l', + 'i','a','b','l','e','t','h','a','n','m','y','o','w','n','m','e', + 'a','n','d','e','r','i','n','g','e','x','p','e','r','i','e','n', + 'c','e','I','w','i','l','l','d','i','s','p','e','n','s','e','t', + 'h','i','s','a','d','v','i','c','e','n','o','w','E','n','j','o', + 'y','t','h','e','p','o','w','e','r','a','n','d','b','e','a','u', + 't','y','o','f','y','o','u','r','y','o','u','t','h','O','h','n', + 'e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n', + 'o','t','u','n','d','e','r','s','t','a','n','d','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','u','n','t','i','l','t','h','e', + 'y','v','e','f','a','d','e','d','B','u','t','t','r','u','s','t', + 'm','e','i','n','2','0','y','e','a','r','s','y','o','u','l','l', + 'l','o','o','k','b','a','c','k','a','t','p','h','o','t','o','s', + 'o','f','y','o','u','r','s','e','l','f','a','n','d','r','e','c', + 'a','l','l','i','n','a','w','a','y','y','o','u','c','a','n','t', + 'g','r','a','s','p','n','o','w','h','o','w','m','u','c','h','p', + 'o','s','s','i','b','i','l','i','t','y','l','a','y','b','e','f', + 'o','r','e','y','o','u','a','n','d','h','o','w','f','a','b','u', + 'l','o','u','s','y','o','u','r','e','a','l','l','y','l','o','o', + 'k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a', + 't','a','s','y','o','u','i','m','a','g','i','n','e','D','o','n', + 't','w','o','r','r','y','a','b','o','u','t','t','h','e','f','u', + 't','u','r','e','O','r','w','o','r','r','y','b','u','t','k','n', + 'o','w','t','h','a','t','K','u','r','t','V','o','n','n','e','g', + 'u','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','s','u', + 'n','s','c','r','e','e','n','w','o','u','l','d','b','e','i','t', + 'T','h','e','l','o','n','g','t','e','r','m','b','e','n','e','f', + 'i','t','s','o','f','s','u','n','s','c','r','e','e','n','h','a', + 'v','e','b','e','e','n','p','r','o','v','e','d','b','y','s','c', + 'i','e','n','t','i','s','t','s','w','h','e','r','e','a','s','t', + 'h','e','r','e','s','t','o','f','m','y','a','d','v','i','c','e', + 'h','a','s','n','o','b','a','s','i','s','m','o','r','e','r','e', + 'l','i','a','b','l','e','t','h','a','n','m','y','o','w','n','m', + 'e','a','n','d','e','r','i','n','g','e','x','p','e','r','i','e', + 'n','c','e','I','w','i','l','l','d','i','s','p','e','n','s','e', + 't','h','i','s','a','d','v','i','c','e','n','o','w','E','n','j', + 'o','y','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','O','h', + 'n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l', + 'n','o','t','u','n','d','e','r','s','t','a','n','d','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','u','n','t','i','l','t','h', + 'e','y','v','e','f','a','d','e','d','B','u','t','t','r','u','s', + 't','m','e','i','n','2','0','y','e','a','r','s','y','o','u','l', + 'l','l','o','o','k','b','a','c','k','a','t','p','h','o','t','o', + 's','o','f','y','o','u','r','s','e','l','f','a','n','d','r','e', + 'c','a','l','l','i','n','a','w','a','y','y','o','u','c','a','n', + 't','g','r','a','s','p','n','o','w','h','o','w','m','u','c','h', + 'p','o','s','s','i','b','i','l','i','t','y','l','a','y','b','e', + 'f','o','r','e','y','o','u','a','n','d','h','o','w','f','a','b', + 'u','l','o','u','s','y','o','u','r','e','a','l','l','y','l','o', + 'o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f', + 'a','t','a','s','y','o','u','i','m','a','g','i','n','e','D','o', + 'n','t','w','o','r','r','y','a','b','o','u','t','t','h','e','f', + 'u','t','u','r','e','O','r','w','o','r','r','y','b','u','t','k', + 'n','o','w','t','h','a','t','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + '\n', 'l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','\n' +}; diff --git a/all_pairs/source/rijndael_enc/rijndael_enc.c b/all_pairs/source/rijndael_enc/rijndael_enc.c new file mode 100644 index 0000000..f74d595 --- /dev/null +++ b/all_pairs/source/rijndael_enc/rijndael_enc.c @@ -0,0 +1,238 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: rijndael_enc + + Author: Dr Brian Gladman + + Function: rijndael_enc is an implementation of the AES encryption + algorithm (Rijndael). + + Source: security section of MiBench + + Changes: Add computation of a checksum, refactoring + + License: see below + +*/ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +#include "../extra.h" +#include "aes.h" +#include "rijndael_enc_libc.h" + +/* + Global variable definitions +*/ +unsigned char rijndael_enc_key[32]; +int rijndael_enc_key_len; + +extern unsigned char rijndael_enc_data[]; +struct rijndael_enc_FILE rijndael_enc_fin; + +int rijndael_enc_checksum = 0; + +/* + Forward declaration of functions +*/ +void rijndael_enc_init( void ); +int rijndael_enc_return( void ); +void rijndael_enc_fillrand( unsigned char *buf, int len ); +void rijndael_enc_encfile( struct rijndael_enc_FILE *fin, struct aes *ctx ); +void rijndael_enc_main( void ); + +void rijndael_enc_init( void ) +{ + /* create a pseudo-file for the input*/ + rijndael_enc_fin.data = rijndael_enc_data; + rijndael_enc_fin.size = 31369; + rijndael_enc_fin.cur_pos = 0; + + unsigned i; + volatile int x = 0; + rijndael_enc_fin.size ^= x; + _Pragma( "loopbound min 31369 max 31369" ) + for ( i = 0; i < rijndael_enc_fin.size; i++ ) + rijndael_enc_fin.data[i] ^= x; + + /* this is a pointer to the hexadecimal key digits */ + const volatile char *cp = + "1234567890abcdeffedcba09876543211234567890abcdeffedcba0987654321"; + char ch; + int by = 0; + + i = 0; /* this is a count for the input digits processed */ + _Pragma( "loopbound min 64 max 64" ) + while ( i < 64 && *cp ) { /* the maximum key length is 32 bytes and */ + /* hence at most 64 hexadecimal digits */ + ch = rijndael_enc_toupper( *cp++ ); /* process a hexadecimal digit */ + if ( ch >= '0' && ch <= '9' ) + by = ( by << 4 ) + ch - '0'; + else + if ( ch >= 'A' && ch <= 'F' ) + by = ( by << 4 ) + ch - 'A' + 10; + else { /* error if not hexadecimal */ + rijndael_enc_checksum = -2; + return; + } + + /* store a key byte for each pair of hexadecimal digits */ + if ( i++ & 1 ) + rijndael_enc_key[i / 2 - 1] = by & 0xff; + } + + if ( *cp ) { + rijndael_enc_checksum = -3; + return; + } else + if ( i < 32 || ( i & 15 ) ) { + rijndael_enc_checksum = -4; + return; + } + + rijndael_enc_key_len = i / 2; +} + +int rijndael_enc_return( void ) +{ + return ( ( rijndael_enc_checksum == ( int )249509 ) ? 0 : -1 ); +} + +/* A Pseudo Random Number Generator (PRNG) used for the */ +/* Initialisation Vector. The PRNG is George Marsaglia's */ +/* Multiply-With-Carry (MWC) PRNG that concatenates two */ +/* 16-bit MWC generators: */ +/* x(n)=36969 * x(n-1) + carry mod 2^16 */ +/* y(n)=18000 * y(n-1) + carry mod 2^16 */ +/* to produce a combined PRNG with a period of about 2^60. */ + +#define RAND(a,b) (((a = 36969 * (a & 65535) + (a >> 16)) << 16) + (b = 18000 * (b & 65535) + (b >> 16)) ) + +void rijndael_enc_fillrand( unsigned char *buf, int len ) +{ + static unsigned long a[2], mt = 1, count = 4; + static char r[4]; + int i; + + if ( mt ) { + mt = 0; + a[0] = 0xeaf3; + a[1] = 0x35fe; + } + + _Pragma( "loopbound min 1 max 16" ) + for ( i = 0; i < len; ++i ) { + if ( count == 4 ) { + *( unsigned long * )r = RAND( a[0], a[1] ); + count = 0; + } + + buf[i] = r[count++]; + } +} + +void rijndael_enc_encfile( struct rijndael_enc_FILE *fin, struct aes *ctx ) +{ + unsigned char inbuf[16], outbuf[16]; + long int flen; + unsigned long i = 0, l = 0; + + rijndael_enc_fillrand( outbuf, + 16 ); /* set an IV for CBC mode */ + flen = fin->size; + + rijndael_enc_fillrand( inbuf, + 1 ); /* make top 4 bits of a byte random */ + l = 15; /* and store the length of the last */ + /* block in the lower 4 bits */ + inbuf[0] = ( ( char )flen & 15 ) | ( inbuf[0] & ~15 ); + + /* TODO: this is necessarily an input-dependent loop bound */ + _Pragma( "loopbound min 1961 max 1961" ) + while ( !rijndael_enc_feof( + fin ) ) { /* loop to encrypt the input file */ + /* input 1st 16 bytes to buf[1..16] */ + i = rijndael_enc_fread( inbuf + 16 - l, 1, l, fin ); /* on 1st round byte[0] */ + /* is the length code */ + if ( i < l ) break; /* if end of the input file reached */ + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor in previous cipher text */ + inbuf[i] ^= outbuf[i]; + + rijndael_enc_encrypt( inbuf, outbuf, + ctx ); /* and do the encryption */ + + rijndael_enc_checksum += outbuf[15]; + + /* in all but first round read 16 */ + l = 16; /* bytes into the buffer */ + } + + /* except for files of length less than two blocks we now have one */ + /* byte from the previous block and 'i' bytes from the current one */ + /* to encrypt and 15 - i empty buffer positions. For files of less */ + /* than two blocks (0 or 1) we have i + 1 bytes and 14 - i empty */ + /* buffer position to set to zero since the 'count' byte is extra */ + + if ( l == 15 ) /* adjust for extra byte in the */ + ++i; /* in the first block */ + + if ( i ) { /* if bytes remain to be output */ + _Pragma( "loopbound min 6 max 6" ) + while ( i < 16 ) /* clear empty buffer positions */ + inbuf[i++] = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor in previous cipher text */ + inbuf[i] ^= outbuf[i]; + + rijndael_enc_encrypt( inbuf, outbuf, ctx ); /* encrypt and output it */ + + rijndael_enc_checksum += outbuf[15]; + } +} + +void _Pragma( "entrypoint" ) rijndael_enc_main( void ) +{ + struct aes ctx[1]; + + /* encryption in Cipher Block Chaining mode */ + rijndael_enc_set_key( rijndael_enc_key, rijndael_enc_key_len, enc, ctx ); + rijndael_enc_encfile( &rijndael_enc_fin, ctx ); +} + +int main( int argc, char** argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= 'a' ) && ( c <= 'z' ) ) + return c - 'a' + 'A'; + return c; +} + +unsigned long rijndael_enc_fread( void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_read = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 10 max 16" ) + while ( i < stream->cur_pos + number_of_chars_to_read ) + ( ( unsigned char * )ptr )[i2++] = stream->data[i++]; + stream->cur_pos += number_of_chars_to_read; + return number_of_chars_to_read; +} + +unsigned long rijndael_enc_fwrite( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_write = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 0 max 0" ) + while ( i < stream->cur_pos + number_of_chars_to_write ) + stream->data[i++] = ( ( unsigned char * )ptr )[i2++]; + stream->cur_pos += number_of_chars_to_write; + return number_of_chars_to_write; +} + +int rijndael_enc_fseek( struct rijndael_enc_FILE *stream, long int offset, + Origin origin ) +{ + if ( origin == RIJNDAEL_ENC_SEEK_SET ) { + stream->cur_pos = offset; + return 0; + } else + if ( origin == RIJNDAEL_ENC_SEEK_CUR ) { + stream->cur_pos += offset; + return 0; + } else + if ( origin == RIJNDAEL_ENC_SEEK_END ) { + stream->cur_pos = stream->size + offset; + return 0; + } + return -1; +} + +int rijndael_enc_fgetpos( struct rijndael_enc_FILE *stream, + unsigned *position ) +{ + *position = stream->cur_pos; + return 0; +} + +int rijndael_enc_feof( struct rijndael_enc_FILE *stream ) +{ + return stream->cur_pos == stream->size ? 1 : 0; +} diff --git a/all_pairs/source/rijndael_enc/rijndael_enc_libc.h b/all_pairs/source/rijndael_enc/rijndael_enc_libc.h new file mode 100644 index 0000000..6a01397 --- /dev/null +++ b/all_pairs/source/rijndael_enc/rijndael_enc_libc.h @@ -0,0 +1,24 @@ +#ifndef RIJNDAEL_ENC_LIBC_H +#define RIJNDAEL_ENC_LIBC_H + +int rijndael_enc_toupper ( int c ); + +enum _Origin_ { RIJNDAEL_ENC_SEEK_SET, RIJNDAEL_ENC_SEEK_CUR, RIJNDAEL_ENC_SEEK_END }; +typedef enum _Origin_ Origin; +struct rijndael_enc_FILE { + unsigned char *data; + unsigned long size; + unsigned cur_pos; +}; + +unsigned long rijndael_enc_fread ( void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ); +unsigned long rijndael_enc_fwrite ( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ); +int rijndael_enc_fseek ( struct rijndael_enc_FILE *stream, long int offset, + Origin origin ); +int rijndael_enc_fgetpos( struct rijndael_enc_FILE *stream, + unsigned *position ); +int rijndael_enc_feof ( struct rijndael_enc_FILE *stream ); + +#endif // RIJNDAEL_ENC_LIBC_H diff --git a/all_pairs/source/statemate/ChangeLog.txt b/all_pairs/source/statemate/ChangeLog.txt new file mode 100644 index 0000000..bce75dc --- /dev/null +++ b/all_pairs/source/statemate/ChangeLog.txt @@ -0,0 +1,60 @@ +File: statemate.c +Original provenience: Mälardalen benchmark suite, + http://www.mrtc.mdh.se/projects/wcet/benchmarks.html + +2016-02-02: +- Removed original header comment, replaced by TACLeBench header. +- Removed macro '#define float int' and replaced each 'float' by 'int' (8 in + total) +- Removed unused macro + - #define entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_copy_IDX 1 +- Removed unused variables + - int FH_TUERMODUL_CTRL__N_copy; + - int BLOCK_ERKENNUNG_CTRL__I_EIN_MAX_copy; + - int BLOCK_ERKENNUNG_CTRL__N_copy; + - char FH_TUERMODUL_CTRL__FT; + - char FH_TUERMODUL__COM_OPEN; + - char FH_TUERMODUL__COM_CLOSE; + - char FH_DU__S_FH_TMBFAUFCAN_copy; + - char FH_DU__S_FH_TMBFZUCAN_copy; +- Moved around all the following so that they are in the given order just after +the header + - macro definitions + - forward declarations of fuctions + - declarations of global variables +- Reordered functions in source code: initialization-related functions first, + followed by algorithm core functions, followed by main functions +- Added a new main function that first calls init function then the old main + function sans init +- Annotated statemate_main() as the entry point of the analysis +- Removed seemingly unnecessary empty lines +- Changed remaining floating number literals, all being used for time related + comparisons, to integer literals by multiplying them by 1000 so that the + code is totally floating number free. E.g: + changed 'time - sc_FH_TUERMODUL_CTRL_2375_2 >= 0.5f' + to 'time - sc_FH_TUERMODUL_CTRL_2375_2 >= 500' + Info: All time related variables were already converted to 'unsigned long' +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: statemate_) followed by lowercase letter + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur + + 2016-10-10: + - added statemate_return() function diff --git a/all_pairs/source/statemate/statemate.c b/all_pairs/source/statemate/statemate.c new file mode 100644 index 0000000..379366a --- /dev/null +++ b/all_pairs/source/statemate/statemate.c @@ -0,0 +1,1286 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: statemate + + Author: Friedhelm Stappert, C-LAB, Paderborn, Germany + + Function: This code was automatically generated by + the STAtechart Real-time-Code generator STARC + which was developed at C-LAB. + + The original StateChart specifies an experimental + car window lift control. + + Source: MRTC + http://www.mrtc.mdh.se/projects/wcet/wcet_bench/statemate/statemate.c + + Changes: no major functional changes + + License: may be used, modified, and re-distributed freely + +*/ + +/* + Macro definitions +*/ + +#include "../extra.h" + +#define SYS_bit_get(a,b) (a)[(b)] +#define SYS_bit_clr(a,b) (a)[(b)] = 0 +#define SYS_bit_set(a,b) (a)[(b)] = 1 +#define SYS_bit_cpy(a1,i1,a2,i2) (a1)[(i1)] = (a2)[(i2)] + +#define active_KINDERSICHERUNG_CTRL_IDX 10 +#define active_KINDERSICHERUNG_CTRL_copy_IDX 11 +#define active_KINDERSICHERUNG_CTRL_old_IDX 12 +#define active_FH_TUERMODUL_CTRL_IDX 13 +#define active_FH_TUERMODUL_CTRL_copy_IDX 14 +#define active_FH_TUERMODUL_CTRL_old_IDX 15 +#define active_EINKLEMMSCHUTZ_CTRL_IDX 16 +#define active_EINKLEMMSCHUTZ_CTRL_copy_IDX 17 +#define active_EINKLEMMSCHUTZ_CTRL_old_IDX 18 +#define active_BLOCK_ERKENNUNG_CTRL_IDX 19 +#define active_BLOCK_ERKENNUNG_CTRL_copy_IDX 20 +#define active_BLOCK_ERKENNUNG_CTRL_old_IDX 21 +#define entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX 0 + +#define entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX 4 +#define entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX 5 +#define exited_BEREIT_FH_TUERMODUL_CTRL_IDX 6 +#define exited_BEREIT_FH_TUERMODUL_CTRL_copy_IDX 7 + +#define FH_TUERMODUL_CTRL__END_REVERS_IDX 22 +#define FH_TUERMODUL_CTRL__END_REVERS_copy_IDX 23 +#define FH_TUERMODUL__EINKLEMMUNG_IDX 24 + + +/* + Forward declaration of functions +*/ + +void statemate_init( void ); +void statemate_interface( void ); +void statemate_generic_KINDERSICHERUNG_CTRL( void ); +void statemate_generic_FH_TUERMODUL_CTRL( void ); +void statemate_generic_EINKLEMMSCHUTZ_CTRL( void ); +void statemate_generic_BLOCK_ERKENNUNG_CTRL( void ); +void statemate_FH_DU( void ); +void statemate_main( void ); +int statemate_return ( void ); + + +/* + Declaration of global variables +*/ + +static char statemate_bitlist[64]; +unsigned long +statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy; +unsigned long +statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL; +unsigned long statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_2375_2; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_2352_1; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_2329_1; +int statemate_FH_TUERMODUL_CTRL__N; +int statemate_FH_TUERMODUL_CTRL__N_old; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_1781_10; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_1739_10; +int statemate_FH_TUERMODUL__POSITION; +int statemate_FH_TUERMODUL__I_EIN; +int statemate_FH_TUERMODUL__I_EIN_old; +int statemate_FH_DU__MFH; +int statemate_FH_DU__MFH_copy; +int statemate_FH_DU__POSITION; +int statemate_FH_DU__I_EIN; +int statemate_FH_DU__I_EIN_old; +int statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX; +int statemate_BLOCK_ERKENNUNG_CTRL__N; +int statemate_BLOCK_ERKENNUNG_CTRL__N_old; +char statemate_FH_TUERMODUL_CTRL__INREVERS2; +char statemate_FH_TUERMODUL_CTRL__INREVERS2_copy; +char statemate_FH_TUERMODUL_CTRL__INREVERS1; +char statemate_FH_TUERMODUL_CTRL__INREVERS1_copy; +char statemate_FH_TUERMODUL__SFHZ_ZENTRAL; +char statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old; +char statemate_FH_TUERMODUL__SFHZ_MEC; +char statemate_FH_TUERMODUL__SFHZ_MEC_old; +char statemate_FH_TUERMODUL__SFHA_ZENTRAL; +char statemate_FH_TUERMODUL__SFHA_ZENTRAL_old; +char statemate_FH_TUERMODUL__SFHA_MEC; +char statemate_FH_TUERMODUL__SFHA_MEC_old; +char statemate_FH_TUERMODUL__KL_50; +char statemate_FH_TUERMODUL__BLOCK; +char statemate_FH_TUERMODUL__BLOCK_copy; +char statemate_FH_TUERMODUL__BLOCK_old; +char statemate_FH_TUERMODUL__FT; +char statemate_FH_TUERMODUL__SFHZ; +char statemate_FH_TUERMODUL__SFHZ_copy; +char statemate_FH_TUERMODUL__SFHZ_old; +char statemate_FH_TUERMODUL__SFHA; +char statemate_FH_TUERMODUL__SFHA_copy; +char statemate_FH_TUERMODUL__SFHA_old; +char statemate_FH_TUERMODUL__MFHZ; +char statemate_FH_TUERMODUL__MFHZ_copy; +char statemate_FH_TUERMODUL__MFHZ_old; +char statemate_FH_TUERMODUL__MFHA; +char statemate_FH_TUERMODUL__MFHA_copy; +char statemate_FH_TUERMODUL__MFHA_old; +char statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; +char statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old; +char statemate_FH_DU__KL_50; +char statemate_FH_DU__S_FH_FTZU; +char statemate_FH_DU__S_FH_FTAUF; +char statemate_FH_DU__FT; +char statemate_FH_DU__EKS_LEISTE_AKTIV; +char statemate_FH_DU__EKS_LEISTE_AKTIV_old; +char statemate_FH_DU__S_FH_TMBFAUFCAN; +char statemate_FH_DU__S_FH_TMBFAUFCAN_old; +char statemate_FH_DU__S_FH_TMBFZUCAN; +char statemate_FH_DU__S_FH_TMBFZUCAN_old; +char statemate_FH_DU__S_FH_TMBFZUDISC; +char statemate_FH_DU__S_FH_TMBFZUDISC_old; +char statemate_FH_DU__S_FH_TMBFAUFDISC; +char statemate_FH_DU__S_FH_TMBFAUFDISC_old; +char statemate_FH_DU__S_FH_ZUDISC; +char statemate_FH_DU__S_FH_AUFDISC; +char statemate_FH_DU__DOOR_ID; +char statemate_FH_DU__BLOCK; +char statemate_FH_DU__BLOCK_copy; +char statemate_FH_DU__BLOCK_old; +char statemate_FH_DU__MFHZ; +char statemate_FH_DU__MFHZ_copy; +char statemate_FH_DU__MFHZ_old; +char statemate_FH_DU__MFHA; +char statemate_FH_DU__MFHA_copy; +char statemate_FH_DU__MFHA_old; + +unsigned long statemate_time; +char statemate_stable; +char statemate_step; + +char +statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state; /** 2 bits **/ +char +statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state; /** 1 bits **/ +char statemate_MEC_KINDERSICHERUNG_CTRL_next_state; /** 1 bits **/ +char +statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state; /** 2 bits **/ +char statemate_B_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char statemate_A_FH_TUERMODUL_CTRL_next_state; /** 1 bits **/ +char +statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state; /** 1 bits **/ +char +statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state; /** 2 bits **/ +char +statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state; /** 2 bits **/ +char +statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state; /** 2 bits **/ +char +statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state; /** 2 bits **/ + + +/* + Initialization-related functions +*/ + +void statemate_init( void ) +{ + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + = 0; + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + = 0; + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL = 0; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 0; + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 0; + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 0; + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 0; + statemate_B_FH_TUERMODUL_CTRL_next_state = 0; + statemate_A_FH_TUERMODUL_CTRL_next_state = 0; + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 0; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 0; + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 0; + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 0; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 0; + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 0; + + statemate_interface(); +} /** statemate_init **/ + + +void statemate_interface( void ) +{ + if ( SYS_bit_get( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ) ) + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL = statemate_time; + if ( SYS_bit_get( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ) || + SYS_bit_get( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_IDX ) ) + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + = statemate_time; + if ( ( statemate_sc_FH_TUERMODUL_CTRL_2375_2 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_2375_2 >= 500 ) ) { + statemate_FH_TUERMODUL__MFHA_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2375_2 = 0; + } + if ( ( statemate_sc_FH_TUERMODUL_CTRL_2352_1 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_2352_1 >= 500 ) ) { + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2352_1 = 0; + } + if ( ( statemate_sc_FH_TUERMODUL_CTRL_2329_1 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_2329_1 >= 500 ) ) { + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2329_1 = 0; + } + if ( ( statemate_sc_FH_TUERMODUL_CTRL_1781_10 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_1781_10 >= 500 ) ) + statemate_sc_FH_TUERMODUL_CTRL_1781_10 = 0; + + if ( ( statemate_sc_FH_TUERMODUL_CTRL_1739_10 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_1739_10 >= 500 ) ) + statemate_sc_FH_TUERMODUL_CTRL_1739_10 = 0; + + if ( ( SYS_bit_get( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ) || + statemate_BLOCK_ERKENNUNG_CTRL__N != statemate_BLOCK_ERKENNUNG_CTRL__N_old ) ) + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + = statemate_time; +} /** statemate_interface **/ + + +/* + Algorithm core functions +*/ + +void statemate_generic_KINDERSICHERUNG_CTRL( void ) +{ + if ( SYS_bit_get( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX ) ) { + switch ( statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state ) { + case 1: { /** state ZENTRAL in chart KINDERSICHERUNG_CTRL **/ + if ( !( statemate_FH_TUERMODUL__SFHA_ZENTRAL || + statemate_FH_TUERMODUL__SFHZ_ZENTRAL ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 0; + break; + } + switch ( statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state ) { + case 1: { /** state IN_ZENTRAL in chart KINDERSICHERUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHA_ZENTRAL && + !( statemate_FH_TUERMODUL__SFHA_ZENTRAL_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + !( statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHA_ZENTRAL ) && + statemate_FH_TUERMODUL__SFHA_ZENTRAL_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHZ_ZENTRAL ) && + statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + break; + } + } /** switch statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state **/ + break; + } + case 2: { /** state MEC in chart KINDERSICHERUNG_CTRL **/ + if ( !( statemate_FH_TUERMODUL__SFHA_MEC || + statemate_FH_TUERMODUL__SFHZ_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 0; + break; + } + switch ( statemate_MEC_KINDERSICHERUNG_CTRL_next_state ) { + case 1: { /** state INMEC in chart KINDERSICHERUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHA_MEC && + !( statemate_FH_TUERMODUL__SFHA_MEC_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_MEC && + !( statemate_FH_TUERMODUL__SFHZ_MEC_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHA_MEC ) && + statemate_FH_TUERMODUL__SFHA_MEC_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHZ_MEC ) && + statemate_FH_TUERMODUL__SFHZ_MEC_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + break; + } + } /** switch statemate_MEC_KINDERSICHERUNG_CTRL_next_state **/ + break; + } + case 3: { /** state WAITING in chart KINDERSICHERUNG_CTRL **/ + if ( ( !statemate_FH_TUERMODUL__KL_50 ) && ( statemate_FH_TUERMODUL__SFHZ_MEC && + statemate_FH_TUERMODUL__SFHA_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 2; + break; + } + if ( ( !statemate_FH_TUERMODUL__KL_50 ) && ( statemate_FH_TUERMODUL__SFHZ_MEC && + !statemate_FH_TUERMODUL__SFHA_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 2; + break; + } + if ( ( !statemate_FH_TUERMODUL__KL_50 ) && + ( !statemate_FH_TUERMODUL__SFHZ_MEC && + statemate_FH_TUERMODUL__SFHA_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 2; + break; + } + if ( ( !statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + statemate_FH_TUERMODUL__SFHA_ZENTRAL && + !statemate_FH_TUERMODUL__KL_50 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + statemate_FH_TUERMODUL__SFHA_ZENTRAL ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + !statemate_FH_TUERMODUL__SFHA_ZENTRAL && + !statemate_FH_TUERMODUL__KL_50 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + break; + } + } /** switch statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state **/ + } +} + + +void statemate_generic_FH_TUERMODUL_CTRL( void ) +{ + if ( !SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX ) && + SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_old_IDX ) && + !SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX ) ) { + SYS_bit_clr( statemate_bitlist, entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_clr( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_IDX ); + } + if ( SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX ) ) { + if ( !SYS_bit_get( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX ) ) + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + SYS_bit_clr( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) ) { + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + } + SYS_bit_clr( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + switch ( statemate_B_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state ZAEHLER_WHSP_ZU_HOCH in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL_CTRL__N == 59 && + !( statemate_FH_TUERMODUL_CTRL__N_old == 59 ) ) ) { + statemate_stable = 0; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 3; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + break; + } + case 2: { /** state NICHT_INITIALISIERT in chart FH_TUERMODUL_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL__BLOCK && + !( statemate_FH_TUERMODUL__BLOCK_old ) ) ) && + ( ( statemate_FH_TUERMODUL__MFHZ ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2329_1 = statemate_time; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 3; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state ) { + case 1: { /** state SCHLIESSEN in chart NICHT_INITIALISIERT **/ + if ( !( statemate_FH_TUERMODUL__SFHZ ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + break; + } + case 2: { /** state OEFFNEN in chart NICHT_INITIALISIERT **/ + if ( !( statemate_FH_TUERMODUL__SFHA ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + break; + } + case 3: { /** state BEREIT in chart NICHT_INITIALISIERT **/ + if ( ( statemate_FH_TUERMODUL__SFHA ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 1; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 2; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 1; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + } /** switch statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state **/ + break; + } + case 3: { /** state INITIALISIERT in chart FH_TUERMODUL_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL_CTRL__N > 60 && + !( statemate_FH_TUERMODUL_CTRL__N_old > 60 ) ) ) && + ( ( !( statemate_FH_TUERMODUL_CTRL__INREVERS1 || + statemate_FH_TUERMODUL_CTRL__INREVERS2 ) ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + if ( ( ( statemate_FH_TUERMODUL__BLOCK && + !( statemate_FH_TUERMODUL__BLOCK_old ) ) ) && + ( ( statemate_FH_TUERMODUL__MFHA ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2375_2 = statemate_time; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + if ( ( ( statemate_FH_TUERMODUL__BLOCK && + !( statemate_FH_TUERMODUL__BLOCK_old ) ) ) && + ( ( statemate_FH_TUERMODUL__MFHZ ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2352_1 = statemate_time; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + switch ( statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state OEFFNEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__POSITION >= 405 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state TIPP_OEFFNEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHZ && + !( statemate_FH_TUERMODUL__SFHZ_old ) ) || + ( statemate_FH_TUERMODUL__SFHA && !( statemate_FH_TUERMODUL__SFHA_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 0; + break; + } + break; + } + case 2: { /** state MAN_OEFFNEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHZ && + !( statemate_FH_TUERMODUL__SFHZ_old ) ) ) { + statemate_stable = 0; + + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHA ) && + statemate_FH_TUERMODUL__SFHA_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 0; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 2; + break; + } + } /** switch statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + case 2: { /** state SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__POSITION <= 0 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state TIPP_SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHA && + !( statemate_FH_TUERMODUL__SFHA_old ) ) || + ( statemate_FH_TUERMODUL__SFHZ && !( statemate_FH_TUERMODUL__SFHZ_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state REVERSIEREN2 in chart FH_TUERMODUL_CTRL **/ + SYS_bit_clr( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 1; + statemate_FH_TUERMODUL_CTRL__INREVERS2_copy = 0; + + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + break; + } + break; + } + case 2: { /** state TIPP_SCHLIESSEN1 in chart FH_TUERMODUL_CTRL **/ + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__INREVERS2_copy = 1; + + SYS_bit_set( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_clr( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_sc_FH_TUERMODUL_CTRL_1781_10 = statemate_time; + statemate_FH_TUERMODUL__MFHA_copy = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + break; + } + } /** switch statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + case 2: { /** state MANUELL_SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( ( !( statemate_FH_TUERMODUL__SFHZ ) && + statemate_FH_TUERMODUL__SFHZ_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state REVERSIEREN1 in chart FH_TUERMODUL_CTRL **/ + SYS_bit_clr( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__INREVERS1_copy = 0; + + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + break; + } + case 2: { /** state MAN_SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_FH_TUERMODUL_CTRL__INREVERS1_copy = 1; + + SYS_bit_set( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_clr( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + + statemate_sc_FH_TUERMODUL_CTRL_1739_10 = statemate_time; + statemate_FH_TUERMODUL__MFHA_copy = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHA && + !( statemate_FH_TUERMODUL__SFHA_old ) ) ) { + statemate_stable = 0; + + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 1; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + } /** switch statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + } /** switch statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + case 3: { /** state BEREIT in chart FH_TUERMODUL_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL__SFHZ && + !( statemate_FH_TUERMODUL__SFHZ_old ) ) ) && + ( ( statemate_FH_TUERMODUL__POSITION > 0 ) ) ) { + statemate_stable = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 2; + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + if ( ( ( statemate_FH_TUERMODUL__SFHA && + !( statemate_FH_TUERMODUL__SFHA_old ) ) ) && + ( ( statemate_FH_TUERMODUL__POSITION < 405 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 1; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 1; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 2; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + } /** switch statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + break; + } + } /** switch statemate_B_FH_TUERMODUL_CTRL_next_state **/ + switch ( statemate_A_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state WIEDERHOLSPERRE in chart FH_TUERMODUL_CTRL **/ + SYS_bit_clr( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + if ( ( statemate_step == 1 && + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + != 0 + && ( statemate_time - + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + == + 1 ) ) && ( ( statemate_FH_TUERMODUL__MFHZ || + statemate_FH_TUERMODUL__MFHA ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__N = statemate_FH_TUERMODUL_CTRL__N + 1; + + statemate_A_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + switch ( statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state WDHSP in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_step == 1 && + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL != 0 && + ( statemate_time - statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL == + 3 ) ) && + ( ( ( !( statemate_FH_TUERMODUL__MFHZ || statemate_FH_TUERMODUL__MFHA ) ) && + statemate_FH_TUERMODUL_CTRL__N > 0 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__N = statemate_FH_TUERMODUL_CTRL__N - 1; + + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + } /** switch statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__N = 0; + statemate_A_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + } /** switch statemate_A_FH_TUERMODUL_CTRL_next_state **/ + SYS_bit_cpy( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX, + statemate_bitlist, entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_copy_IDX, + statemate_bitlist, + exited_BEREIT_FH_TUERMODUL_CTRL_IDX ); + } +} + + +void statemate_generic_EINKLEMMSCHUTZ_CTRL( void ) +{ + if ( SYS_bit_get( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_IDX ) ) { + switch ( statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state ) { + case 1: { /** state NORMALBETRIEB in chart EINKLEMMSCHUTZ_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV && + !( statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old ) ) ) && + ( ( !( statemate_FH_TUERMODUL__SFHZ && + statemate_FH_TUERMODUL__SFHA ) ) ) ) { + statemate_stable = 0; + + SYS_bit_set( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ); + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 2; + break; + } + break; + } + case 2: { /** state EINKLEMMUNG in chart EINKLEMMSCHUTZ_CTRL **/ + SYS_bit_clr( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ); + if ( ( !( statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV ) && + statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old ) ) { + statemate_stable = 0; + + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 1; + break; + } + } /** switch statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state **/ + } +} + + +void statemate_generic_BLOCK_ERKENNUNG_CTRL( void ) +{ + if ( !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) && + SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_old_IDX ) && + !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ) ) + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + if ( SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) ) { + switch ( statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state ) { + case 1: { /** state KEINE_BEWEGUNG in chart BLOCK_ERKENNUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__I_EIN != statemate_FH_TUERMODUL__I_EIN_old ) && + ( ( statemate_FH_TUERMODUL__I_EIN > 0 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__BLOCK_copy = 0; + + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 2; + statemate_BLOCK_ERKENNUNG_CTRL__N = 0; + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX = 2; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 3; + SYS_bit_set( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + break; + } + break; + } + case 2: { /** state BEWEGUNG in chart BLOCK_ERKENNUNG_CTRL **/ + if ( ( !( statemate_FH_TUERMODUL__MFHA ) && + statemate_FH_TUERMODUL__MFHA_old ) || + ( !( statemate_FH_TUERMODUL__MFHZ ) && statemate_FH_TUERMODUL__MFHZ_old ) ) { + statemate_stable = 0; + + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 0; + break; + } + switch ( statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state ) { + case 1: { /** state FENSTER_BLOCKIERT in chart BLOCK_ERKENNUNG_CTRL **/ + break; + } + case 2: { /** state FENSTER_BEWEGT_SICH in chart BLOCK_ERKENNUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__I_EIN > + ( statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX - 2 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__BLOCK_copy = 1; + + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 1; + break; + } + break; + } + case 3: { /** state EINSCHALTSTROM_MESSEN in chart BLOCK_ERKENNUNG_CTRL **/ + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + if ( ( statemate_BLOCK_ERKENNUNG_CTRL__N == 11 && + !( statemate_BLOCK_ERKENNUNG_CTRL__N_old == 11 ) ) ) { + statemate_stable = 0; + + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 2; + break; + } + /** static reactions: **/ + if ( statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state == 3 ) { + if ( statemate_step == 1 && + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + != 0 && ( statemate_time - + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + == 2 ) ) { + statemate_BLOCK_ERKENNUNG_CTRL__N = statemate_BLOCK_ERKENNUNG_CTRL__N + 1; + if ( ( statemate_FH_TUERMODUL__I_EIN > + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX ) ) + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX = statemate_FH_TUERMODUL__I_EIN; + + } + } + /** end static reactions **/ + break; + } + default: { + statemate_stable = 0; + statemate_BLOCK_ERKENNUNG_CTRL__N = 0; + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX = 2; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 3; + SYS_bit_set( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + break; + } + } /** switch statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + break; + } + } /** switch statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state **/ + } +} + + +void statemate_FH_DU( void ) +{ + statemate_time = 1; /**SYS_get_clock()**/ + statemate_stable = 0; + statemate_step = 0; + // patched for wcet: replacing while statement by for + //while (!statemate_stable) + int i; + _Pragma( "loopbound min 100 max 100" ) + for ( i = 0; i < 100; i++ ) { + statemate_stable = 1; + statemate_step++; + { + switch ( statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state ) { + case 1: { /** state SCHLIESSEN in chart FH_STEUERUNG_DUMMY **/ + if ( ( !( statemate_FH_DU__MFHZ ) && statemate_FH_DU__MFHZ_old ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = 0; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 2; + break; + } + break; + } + case 2: { /** state BEREIT in chart FH_STEUERUNG_DUMMY **/ + if ( ( statemate_FH_DU__MFHZ && !( statemate_FH_DU__MFHZ_old ) ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = -100; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 1; + break; + } + if ( ( statemate_FH_DU__MFHA && !( statemate_FH_DU__MFHA_old ) ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = 100; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 3; + break; + } + break; + } + case 3: { /** state OEFFNEN in chart FH_STEUERUNG_DUMMY **/ + if ( ( !( statemate_FH_DU__MFHA ) && statemate_FH_DU__MFHA_old ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = 0; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 2; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_FH_DU__MFH = 0; + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 2; + break; + } + } /** switch statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state **/ + } + { + { + if ( !SYS_bit_get( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX ) ) + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + SYS_bit_clr( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_IDX ) ) + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 1; + SYS_bit_clr( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) ) { + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + } + SYS_bit_clr( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX ) ) { + SYS_bit_clr( statemate_bitlist, entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_clr( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_IDX ); + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + statemate_FH_TUERMODUL_CTRL__N = 0; + statemate_A_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + } + SYS_bit_clr( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX ); + /** static reactions: **/ + if ( statemate_FH_DU__S_FH_TMBFZUCAN != statemate_FH_DU__S_FH_TMBFZUCAN_old ) { + if ( ( !statemate_FH_DU__DOOR_ID ) ) + statemate_FH_DU__S_FH_FTZU = statemate_FH_DU__S_FH_TMBFZUCAN; + + } + if ( statemate_FH_DU__S_FH_TMBFZUDISC != + statemate_FH_DU__S_FH_TMBFZUDISC_old ) { + if ( statemate_FH_DU__DOOR_ID ) + statemate_FH_DU__S_FH_TMBFZUCAN = statemate_FH_DU__S_FH_TMBFZUDISC; + + } + if ( statemate_FH_DU__S_FH_TMBFAUFCAN != + statemate_FH_DU__S_FH_TMBFAUFCAN_old ) { + if ( ( !statemate_FH_DU__DOOR_ID ) ) + statemate_FH_DU__S_FH_FTAUF = statemate_FH_DU__S_FH_TMBFAUFCAN; + + } + if ( statemate_FH_DU__S_FH_TMBFAUFDISC != + statemate_FH_DU__S_FH_TMBFAUFDISC_old ) { + if ( statemate_FH_DU__DOOR_ID ) + statemate_FH_DU__S_FH_TMBFAUFCAN = statemate_FH_DU__S_FH_TMBFAUFDISC; + + } + /** end static reactions **/ + } + } + SYS_bit_cpy( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX, + statemate_bitlist, + active_KINDERSICHERUNG_CTRL_old_IDX ); + SYS_bit_cpy( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX, statemate_bitlist, + active_FH_TUERMODUL_CTRL_old_IDX ); + SYS_bit_cpy( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_IDX, + statemate_bitlist, + active_EINKLEMMSCHUTZ_CTRL_old_IDX ); + SYS_bit_cpy( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX, + statemate_bitlist, + active_BLOCK_ERKENNUNG_CTRL_old_IDX ); + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_KINDERSICHERUNG_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_FH_TUERMODUL_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_EINKLEMMSCHUTZ_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_BLOCK_ERKENNUNG_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + SYS_bit_cpy( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX, + statemate_bitlist, + active_KINDERSICHERUNG_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX, + statemate_bitlist, + active_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX, + statemate_bitlist, + active_EINKLEMMSCHUTZ_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX, + statemate_bitlist, + active_BLOCK_ERKENNUNG_CTRL_IDX ); + statemate_FH_TUERMODUL_CTRL__N_old = statemate_FH_TUERMODUL_CTRL__N; + statemate_FH_TUERMODUL__I_EIN_old = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__MFH = statemate_FH_DU__MFH_copy; + statemate_FH_DU__I_EIN_old = statemate_FH_DU__I_EIN; + statemate_BLOCK_ERKENNUNG_CTRL__N_old = statemate_BLOCK_ERKENNUNG_CTRL__N; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_TUERMODUL__SFHZ_MEC_old = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL_old = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_TUERMODUL__SFHA_MEC_old = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_TUERMODUL__BLOCK = statemate_FH_TUERMODUL__BLOCK_copy; + statemate_FH_TUERMODUL__BLOCK_old = statemate_FH_TUERMODUL__BLOCK; + statemate_FH_TUERMODUL__SFHZ = statemate_FH_TUERMODUL__SFHZ_copy; + statemate_FH_TUERMODUL__SFHZ_old = statemate_FH_TUERMODUL__SFHZ; + statemate_FH_TUERMODUL__SFHA = statemate_FH_TUERMODUL__SFHA_copy; + statemate_FH_TUERMODUL__SFHA_old = statemate_FH_TUERMODUL__SFHA; + statemate_FH_TUERMODUL__MFHZ = statemate_FH_TUERMODUL__MFHZ_copy; + statemate_FH_TUERMODUL__MFHZ_old = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_TUERMODUL__MFHA = statemate_FH_TUERMODUL__MFHA_copy; + statemate_FH_TUERMODUL__MFHA_old = statemate_FH_TUERMODUL__MFHA; + statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old = + statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__EKS_LEISTE_AKTIV_old = statemate_FH_DU__EKS_LEISTE_AKTIV; + statemate_FH_DU__S_FH_TMBFAUFCAN_old = statemate_FH_DU__S_FH_TMBFAUFCAN; + statemate_FH_DU__S_FH_TMBFZUCAN_old = statemate_FH_DU__S_FH_TMBFZUCAN; + statemate_FH_DU__S_FH_TMBFZUDISC_old = statemate_FH_DU__S_FH_TMBFZUDISC; + statemate_FH_DU__S_FH_TMBFAUFDISC_old = statemate_FH_DU__S_FH_TMBFAUFDISC; + statemate_FH_DU__BLOCK = statemate_FH_DU__BLOCK_copy; + statemate_FH_DU__BLOCK_old = statemate_FH_DU__BLOCK; + statemate_FH_DU__MFHZ = statemate_FH_DU__MFHZ_copy; + statemate_FH_DU__MFHZ_old = statemate_FH_DU__MFHZ; + statemate_FH_DU__MFHA = statemate_FH_DU__MFHA_copy; + statemate_FH_DU__MFHA_old = statemate_FH_DU__MFHA; + + } /** while(!statemate_stable) **/ + +} /** statemate_FH_DU **/ + + +/* + Main functions +*/ + +int statemate_return() +{ + unsigned long int checksum = 0; + int index; + for ( index=63 ; index>=0 ; index-- ){ + checksum += (unsigned long) (statemate_bitlist[index] << index); + } + return(checksum == 18446744073709551614ul); +} + +void _Pragma ( "entrypoint" ) statemate_main( void ) +{ + statemate_FH_DU(); +} + + +int main ( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete +//#include + +/* A representation of a double as a union. */ +union ieee754_double +{ + double d; + + /* This is the IEEE 754 double-precision format. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + } ieee_nan; +}; + +/* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +/* #if __FLOAT_WORD_ORDER == BIG_ENDIAN */ +/* #warning USING Big Endian float word order */ +/* typedef union */ +/* { */ +/* double value; */ +/* struct */ +/* { */ +/* u_int16_t msw; */ +/* u_int16_t lsw; */ +/* } parts; */ +/* } ieeeDoubleShapeType; */ + +/* #endif */ + +/* #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN */ +/* #warning USING Little Endian float word order */ + +typedef union +{ + double value; + struct + { + u_int16_t lsw; + u_int16_t msw; + } parts; +} ieeeDoubleShapeType; + +/* #endif */ + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +{ \ + ieeeDoubleShapeType ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +{ \ + ieeeDoubleShapeType iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + u_int32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +{ \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +{ \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} + + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/all_pairs/source/susan/susan.c b/all_pairs/source/susan/susan.c new file mode 100644 index 0000000..fb990b1 --- /dev/null +++ b/all_pairs/source/susan/susan.c @@ -0,0 +1,2014 @@ +/**********************************************************************\ + + SUSAN Version 2l by Stephen Smith + Oxford Centre for Functional Magnetic Resonance Imaging of the Brain, + Department of Clinical Neurology, Oxford University, Oxford, UK + (Previously in Computer Vision and Image Processing Group - now + Computer Vision and Electro Optics Group - DERA Chertsey, UK) + Email: steve@fmrib.ox.ac.uk + WWW: http://www.fmrib.ox.ac.uk/~steve + + (C) Crown Copyright (1995-1999), Defence Evaluation and Research Agency, + Farnborough, Hampshire, GU14 6TD, UK + DERA WWW site: + http://www.dera.gov.uk/ + DERA Computer Vision and Electro Optics Group WWW site: + http://www.dera.gov.uk/imageprocessing/dera/group_home.html + DERA Computer Vision and Electro Optics Group point of contact: + Dr. John Savage, jtsavage@dera.gov.uk, +44 1344 633203 + + A UK patent has been granted: "Method for digitally processing + images to determine the position of edges and/or corners therein for + guidance of unmanned vehicle", UK Patent 2272285. Proprietor: + Secretary of State for Defence, UK. 15 January 1997 + + This code is issued for research purposes only and remains the + property of the UK Secretary of State for Defence. This code must + not be passed on without this header information being kept + intact. This code must not be sold. + +\**********************************************************************/ + +/**********************************************************************\ + + SUSAN Version 2l + SUSAN = Smallest Univalue Segment Assimilating Nucleus + + Email: steve@fmrib.ox.ac.uk + WWW: http://www.fmrib.ox.ac.uk/~steve + + Related paper: + @article{Smith97, + author = "Smith, S.M. and Brady, J.M.", + title = "{SUSAN} - A New Approach to Low Level Image Processing", + journal = "Int. Journal of Computer Vision", + pages = "45--78", + volume = "23", + number = "1", + month = "May", + year = 1997} + + To be registered for automatic (bug) updates of SUSAN, send an email. + + Compile with: + gcc -O4 -o susan susan2l.c -lm + + See following section for different machine information. Please + report any bugs (and fixes). There are a few optional changes that + can be made in the "defines" section which follows shortly. + + Usage: type "susan" to get usage. Only PGM format files can be input + and output. Utilities such as the netpbm package and XV can be used + to convert to and from other formats. Any size of image can be + processed. + + This code is written using an emacs folding mode, making moving + around the different sections very easy. This is why there are + various marks within comments and why comments are indented. + + + SUSAN QUICK: + + This version of the SUSAN corner finder does not do all the + false-corner suppression and thus is faster and produced some false + positives, particularly on strong edges. However, because there are + less stages involving thresholds etc., the corners that are + correctly reported are usually more stable than those reported with + the full algorithm. Thus I recommend at least TRYING this algorithm + for applications where stability is important, e.g., tracking. + + THRESHOLDS: + + There are two thresholds which can be set at run-time. These are the + brightness threshold (t) and the distance threshold (d). + + SPATIAL CONTROL: d + + In SUSAN smoothing d controls the size of the Gaussian mask; its + default is 4.0. Increasing d gives more smoothing. In edge finding, + a fixed flat mask is used, either 37 pixels arranged in a "circle" + (default), or a 3 by 3 mask which gives finer detail. In corner + finding, only the larger 37 pixel mask is used; d is not + variable. In smoothing, the flat 3 by 3 mask can be used instead of + a larger Gaussian mask; this gives low smoothing and fast operation. + + BRIGHTNESS CONTROL: t + + In all three algorithms, t can be varied (default=20); this is the + main threshold to be varied. It determines the maximum difference in + greylevels between two pixels which allows them to be considered + part of the same "region" in the image. Thus it can be reduced to + give more edges or corners, i.e. to be more sensitive, and vice + versa. In smoothing, reducing t gives less smoothing, and vice + versa. Set t=10 for the test image available from the SUSAN web + page. + + ITERATIONS: + + With SUSAN smoothing, more smoothing can also be obtained by + iterating the algorithm several times. This has a different effect + from varying d or t. + + FIXED MASKS: + + 37 pixel mask: ooo 3 by 3 mask: ooo + ooooo ooo + ooooooo ooo + ooooooo + ooooooo + ooooo + ooo + + CORNER ATTRIBUTES dx, dy and I + (Only read this if you are interested in the C implementation or in + using corner attributes, e.g., for corner matching) + + Corners reported in the corner list have attributes associated with + them as well as positions. This is useful, for example, when + attempting to match corners from one image to another, as these + attributes can often be fairly unchanged between images. The + attributes are dx, dy and I. I is the value of image brightness at + the position of the corner. In the case of susan_corners_quick, dx + and dy are the first order derivatives (differentials) of the image + brightness in the x and y directions respectively, at the position + of the corner. In the case of normal susan corner finding, dx and dy + are scaled versions of the position of the centre of gravity of the + USAN with respect to the centre pixel (nucleus). + + BRIGHTNESS FUNCTION LUT IMPLEMENTATION: + (Only read this if you are interested in the C implementation) + + The SUSAN brightness function is implemented as a LUT + (Look-Up-Table) for speed. The resulting pointer-based code is a + little hard to follow, so here is a brief explanation. In + setup_brightness_lut() the LUT is setup. This mallocs enough space + for *bp and then repositions the pointer to the centre of the + malloced space. The SUSAN function e^-(x^6) or e^-(x^2) is + calculated and converted to a uchar in the range 0-100, for all + possible image brightness differences (including negative + ones). Thus bp[23] is the output for a brightness difference of 23 + greylevels. In the SUSAN algorithms this LUT is used as follows: + + p=in + (i-3)*x_size + j - 1; + p points to the first image pixel in the circular mask surrounding + point (x,y). + + cp=bp + in[i*x_size+j]; + cp points to a position in the LUT corresponding to the brightness + of the centre pixel (x,y). + + now for every pixel within the mask surrounding (x,y), + n+=*(cp-*p++); + the brightness difference function is found by moving the cp pointer + down by an amount equal to the value of the pixel pointed to by p, + thus subtracting the two brightness values and performing the + exponential function. This value is added to n, the running USAN + area. + + in SUSAN smoothing, the variable height mask is implemented by + multiplying the above by the moving mask pointer, reset for each new + centre pixel. + tmp = *dpt++ * *(cp-brightness); + +\**********************************************************************/ + +/**********************************************************************\ + + Success has been reported with the following: + + MACHINE OS COMPILER + + Sun 4.1.4 bundled C, gcc + + Next + + SGI IRIX SGI cc + + DEC Unix V3.2+ + + IBM RISC AIX gcc + + PC Borland 5.0 + + PC Linux gcc-2.6.3 + + PC Win32 Visual C++ 4.0 (Console Application) + + PC Win95 Visual C++ 5.0 (Console Application) + Thanks to Niu Yongsheng : + Use the FOPENB option below + + PC DOS djgpp gnu C + Thanks to Mark Pettovello : + Use the FOPENB option below + + HP HP-UX bundled cc + Thanks to Brian Dixon : + in ksh: + export CCOPTS="-Aa -D_HPUX_SOURCE | -lM" + cc -O3 -o susan susan2l.c + +\**********************************************************************/ + +/**********************************************************************\ + + SUSAN Version 2l, 12/2/99 + Changed GNUDOS option to FOPENB. + (Thanks to Niu Yongsheng .) + Took out redundant "sq=sq/2;". + + SUSAN Version 2k, 19/8/98: + In corner finding: + Changed if(yyx_size) etc. tests in smoothing. + Added a couple of free() calls for cgx and cgy. + (Thanks to geoffb@ucs.ed.ac.uk - Geoff Browitt.) + + SUSAN Version 2i, 21/7/97: + Added information about corner attributes. + + SUSAN Version 2h, 16/12/96: + Added principle (initial enhancement) option. + + SUSAN Version 2g, 2/7/96: + Minor superficial changes to code. + + SUSAN Version 2f, 16/1/96: + Added GNUDOS option (now called FOPENB; see options below). + + SUSAN Version 2e, 9/1/96: + Added -b option. + Fixed 1 pixel horizontal offset error for drawing edges. + + SUSAN Version 2d, 27/11/95: + Fixed loading of certain PGM files in get_image (again!) + + SUSAN Version 2c, 22/11/95: + Fixed loading of certain PGM files in get_image. + (Thanks to qu@San-Jose.ate.slb.com - Gongyuan Qu.) + + SUSAN Version 2b, 9/11/95: + removed "z==" error in edges routines. + + SUSAN Version 2a, 6/11/95: + Removed a few unnecessary variable declarations. + Added different machine information. + Changed "header" in get_image to char. + + SUSAN Version 2, 1/11/95: first combined version able to take any + image sizes. + + SUSAN "Versions 1", circa 1992: the various SUSAN algorithms were + developed during my doctorate within different programs and for + fixed image sizes. The algorithms themselves are virtually unaltered + between "versions 1" and the combined program, version 2. + +\**********************************************************************/ + +#include "../extra.h" +#include "wcclibm.h" +#include "wccfile.h" +#include "wccmalloc.h" + +#define EXP_A 184 +#define EXP_C 16249 + +float susan_expf(float y) +{ + union + { + float d; + struct + { +#ifdef LITTLE_ENDIAN + short j, i; +#else + short i, j; +#endif + } n; + } eco; + eco.n.i = EXP_A*(y) + (EXP_C); + eco.n.j = 0; + return eco.d; +} + +float susan_sqrtf(float val) +{ + float x = val/10; + + float dx; + + float diff; + float min_tol = 0.00001f; + + int i, flag; + + + flag = 0; + if (val == 0 ) x = 0; + else { + for (i=1;i<20;i++) + { + if (!flag) { + dx = (val - (x*x)) / (2.0f * x); + x = x + dx; + diff = val - (x*x); + if (fabs(diff) <= min_tol) flag = 1; + } + } + } + return (x); +} + +/* ********** Optional settings */ + +typedef int TOTAL_TYPE; + +#define SEVEN_SUPP /* size for non-max corner suppression; SEVEN_SUPP or FIVE_SUPP */ +#define MAX_CORNERS 15000 /* max corners per frame */ + +#define FTOI(a) ( (a) < 0 ? ((int)(a-0.5)) : ((int)(a+0.5)) ) +#define abs(a) ( (a) < 0 ? -a : a ) +typedef unsigned char uchar; +typedef struct {int x,y,info, dx, dy, I;} corner_rep; +typedef corner_rep CORNER_LIST[MAX_CORNERS]; + +extern char susan_input[7292]; +struct wccFILE susan_file; +float susan_dt; +int susan_bt; +int susan_principle_conf; +int susan_thin_post_proc; +int susan_three_by_three; +int susan_drawing_mode; +int susan_susan_quick; +int susan_max_no_corners; +int susan_max_no_edges; + +int susan_getint( struct wccFILE *fd ) +{ + int c, i; + char dummy[10000]; + + c = susan_wccfgetc(fd); + _Pragma( "loopbound min 1 max 4" ) + while (1) { /* find next integer */ + if (c=='#') /* if we're at a comment, read to end of line */ + susan_wccfgets(dummy,9000,fd); + if (c==EOFX) { + /* "Image is not binary PGM." */ + } + if (c>='0' && c<='9') + break; /* found what we were looking for */ + c = susan_wccfgetc(fd); + } + + /* we're at the start of a number, continue until we hit a non-number */ + i = 0; + _Pragma( "loopbound min 2 max 3" ) + while (1) { + i = (i*10) + (c - '0'); + c = susan_wccfgetc(fd); + if (c==EOFX) return (i); + if (c<'0' || c>'9') break; + } + + return (i); +} + + +void susan_get_image( struct wccFILE *fd, + unsigned char **in, int *x_size, int *y_size ) +{ + char header [100]; + + susan_wccfseek( fd, 0, WCCSEEK_SET ); + + /* {{{ read header */ + + header[0]=susan_wccfgetc( fd ); + header[1]=susan_wccfgetc( fd ); + if(!(header[0]=='P' && header[1]=='5')) { + /* "Image does not have binary PGM header." */ + } + + *x_size = susan_getint(fd); + *y_size = susan_getint(fd); + // dummy read + susan_getint(fd); + +/* }}} */ + + *in = (uchar *) susan_wccmalloc(*x_size * *y_size); + + if (susan_wccfread(*in,1,*x_size * *y_size,fd) == 0) { + /* "Image is wrong size.\n" */ + } +} + + +void susan_put_image( int x_size, int y_size ) +{ + int i; + _Pragma( "loopbound min 7220 max 7220" ) + for ( i = 0; i < x_size*y_size; i++ ) { + ; + } +} + + +void susan_int_to_uchar( char *r, uchar *in, int size ) +{ + int i, max_r=r[0], min_r=r[0]; + + _Pragma( "loopbound min 0 max 0" ) + for (i=0; i max_r ) + max_r=r[i]; + if ( r[i] < min_r ) + min_r=r[i]; + } + + if (max_r == min_r) { + /* Should not occur in TACLeBench. */ + _Pragma( "loopbound min 0 max 0" ) + for (i=0; ip[l+1]) { + tmp=p[l]; + p[l]=p[l+1]; + p[l+1]=tmp; + } + } + } + + return( (p[3]+p[4]) / 2 ); +} + + +/* this enlarges "in" so that borders can be dealt with easily */ +void susan_enlarge( uchar **in, uchar *tmp_image, + int *x_size, int *y_size, int border ) +{ + int i, j; + + _Pragma( "loopbound min 95 max 95" ) + for(i=0; i<*y_size; i++) { /* copy *in into tmp_image */ + susan_wccmemcpy( tmp_image+(i+border)*(*x_size+2*border)+border, + *in+i* *x_size, *x_size); + } + + _Pragma( "loopbound min 7 max 7" ) + for(i=0; i15 ) { + /* "Distance_thresh too big for integer arithmetic." */ + // Either reduce it to <=15 or recompile with variable "total" + // as a float: see top "defines" section. + } + + if ( (2*mask_size+1>x_size) || (2*mask_size+1>y_size) ) { + /* "Mask size too big for image." */ + } + + tmp_image = (uchar *)susan_wccmalloc( (x_size+mask_size*2) * (y_size+mask_size*2) ); + susan_enlarge(&in,tmp_image,&x_size,&y_size,mask_size); + + if (three_by_three==0) { + /* large Gaussian masks */ + /* {{{ setup distance lut */ + + n_max = (mask_size*2) + 1; + + increment = x_size - n_max; + + dp = (unsigned char *)susan_wccmalloc(n_max*n_max); + dpt = dp; + temp = -(dt*dt); + + _Pragma( "loopbound min 15 max 15" ) + for(i=-mask_size; i<=mask_size; i++) { + _Pragma( "loopbound min 15 max 15" ) + for(j=-mask_size; j<=mask_size; j++) { + x = (int) (100.0 * susan_expf( ((float)((i*i)+(j*j))) / temp )); + *dpt++ = (unsigned char)x; + } + } + + /* {{{ main section */ + + _Pragma( "loopbound min 95 max 95" ) + for (i=mask_size;im) { m=l[y+y+y+x]; a=y; b=x; } + + if (m>0) { + if (mid[i*x_size+j]<4) + mid[(i+a-1)*x_size+j+b-1] = 4; + else + mid[(i+a-1)*x_size+j+b-1] = mid[i*x_size+j]+1; + if ( (a+a+b) < 3 ) { /* need to jump back in image */ + i+=a-1; + j+=b-2; + if (i<4) i=4; + if (j<4) j=4; + } + } + } + + /* {{{ n==2 */ + + if (n==2) { + /* put in a bit here to straighten edges */ + b00 = mid[(i-1)*x_size+j-1]<8; /* corners of 3x3 */ + b02 = mid[(i-1)*x_size+j+1]<8; + b20 = mid[(i+1)*x_size+j-1]<8; + b22 = mid[(i+1)*x_size+j+1]<8; + if ( ((b00+b02+b20+b22)==2) && ((b00|b22)&(b02|b20))) { + /* case: move a point back into line. + e.g. X O X CAN become X X X + O X O O O O + O O O O O O */ + if (b00) { + if (b02) { x=0; y=-1; } + else { x=-1; y=0; } + } else { + if (b02) { x=1; y=0; } + else { x=0; y=1; } + } + if (((float)r[(i+y)*x_size+j+x]/(float)centre) > 0.7) { + if ( ( (x==0) && (mid[(i+(2*y))*x_size+j]>7) && (mid[(i+(2*y))*x_size+j-1]>7) && (mid[(i+(2*y))*x_size+j+1]>7) ) || + ( (y==0) && (mid[(i)*x_size+j+(2*x)]>7) && (mid[(i+1)*x_size+j+(2*x)]>7) && (mid[(i-1)*x_size+j+(2*x)]>7) ) ) { + mid[(i)*x_size+j]=100; + mid[(i+y)*x_size+j+x]=3; /* no jumping needed */ + } + } + } else { + b01 = mid[(i-1)*x_size+j ]<8; + b12 = mid[(i )*x_size+j+1]<8; + b21 = mid[(i+1)*x_size+j ]<8; + b10 = mid[(i )*x_size+j-1]<8; + /* {{{ right angle ends - not currently used */ + +#ifdef IGNORETHIS + if ( (b00&b01)|(b00&b10)|(b02&b01)|(b02&b12)|(b20&b10)|(b20&b21)|(b22&b21)|(b22&b12) ) { + /* case; right angle ends. clean up. + e.g.; X X O CAN become X X O + O X O O O O + O O O O O O */ + if ( ((b01)&(mid[(i-2)*x_size+j-1]>7)&(mid[(i-2)*x_size+j]>7)&(mid[(i-2)*x_size+j+1]>7)& + ((b00&((2*r[(i-1)*x_size+j+1])>centre))|(b02&((2*r[(i-1)*x_size+j-1])>centre)))) | + ((b10)&(mid[(i-1)*x_size+j-2]>7)&(mid[(i)*x_size+j-2]>7)&(mid[(i+1)*x_size+j-2]>7)& + ((b00&((2*r[(i+1)*x_size+j-1])>centre))|(b20&((2*r[(i-1)*x_size+j-1])>centre)))) | + ((b12)&(mid[(i-1)*x_size+j+2]>7)&(mid[(i)*x_size+j+2]>7)&(mid[(i+1)*x_size+j+2]>7)& + ((b02&((2*r[(i+1)*x_size+j+1])>centre))|(b22&((2*r[(i-1)*x_size+j+1])>centre)))) | + ((b21)&(mid[(i+2)*x_size+j-1]>7)&(mid[(i+2)*x_size+j]>7)&(mid[(i+2)*x_size+j+1]>7)& + ((b20&((2*r[(i+1)*x_size+j+1])>centre))|(b22&((2*r[(i+1)*x_size+j-1])>centre)))) ) { + mid[(i)*x_size+j]=100; + if (b10&b20) j-=2; + if (b00|b01|b02) { i--; j-=2; } + } + } +#endif + + if ( ((b01+b12+b21+b10)==2) && ((b10|b12)&(b01|b21)) && + ((b01&((mid[(i-2)*x_size+j-1]<8)|(mid[(i-2)*x_size+j+1]<8)))|(b10&((mid[(i-1)*x_size+j-2]<8)|(mid[(i+1)*x_size+j-2]<8)))| + (b12&((mid[(i-1)*x_size+j+2]<8)|(mid[(i+1)*x_size+j+2]<8)))|(b21&((mid[(i+2)*x_size+j-1]<8)|(mid[(i+2)*x_size+j+1]<8)))) ) { + /* case; clears odd right angles. + e.g.; O O O becomes O O O + X X O X O O + O X O O X O */ + mid[(i)*x_size+j]=100; + i--; /* jump back */ + j-=2; + if (i<4) i=4; + if (j<4) j=4; + } + } + } + + /* {{{ n>2 the thinning is done here without breaking connectivity */ + + if (n>2) { + b01 = mid[(i-1)*x_size+j ]<8; + b12 = mid[(i )*x_size+j+1]<8; + b21 = mid[(i+1)*x_size+j ]<8; + b10 = mid[(i )*x_size+j-1]<8; + if((b01+b12+b21+b10)>1) { + b00 = mid[(i-1)*x_size+j-1]<8; + b02 = mid[(i-1)*x_size+j+1]<8; + b20 = mid[(i+1)*x_size+j-1]<8; + b22 = mid[(i+1)*x_size+j+1]<8; + p1 = b00 | b01; + p2 = b02 | b12; + p3 = b22 | b21; + p4 = b20 | b10; + + if( ((p1 + p2 + p3 + p4) - ((b01 & p2)+(b12 & p3)+(b21 & p4)+(b10 & p1))) < 2) { + mid[(i)*x_size+j]=100; + i--; + j-=2; + if (i<4) i=4; + if (j<4) j=4; + } + } + } + } + } + } +} + + +void susan_edges( uchar *in, char *r, uchar *mid, uchar *bp, + int max_no, int x_size, int y_size ) +{ + float z; + int do_symmetry, i, j, m, n, a, b, x, y, w; + uchar c,*p,*cp; + + susan_wccmemset(r,0,x_size * y_size); + + _Pragma( "loopbound min 89 max 89" ) + for (i=3;i0) { + m=r[i*x_size+j]; + n=max_no - m; + cp=bp + in[i*x_size+j]; + + if (n>600) { + p=in + (i-3)*x_size + j - 1; + x=0;y=0; + + c=*(cp-*p++);x-=c;y-=3*c; + c=*(cp-*p++);y-=3*c; + c=*(cp-*p);x+=c;y-=3*c; + p+=x_size-3; + + c=*(cp-*p++);x-=2*c;y-=2*c; + c=*(cp-*p++);x-=c;y-=2*c; + c=*(cp-*p++);y-=2*c; + c=*(cp-*p++);x+=c;y-=2*c; + c=*(cp-*p);x+=2*c;y-=2*c; + p+=x_size-5; + + c=*(cp-*p++);x-=3*c;y-=c; + c=*(cp-*p++);x-=2*c;y-=c; + c=*(cp-*p++);x-=c;y-=c; + c=*(cp-*p++);y-=c; + c=*(cp-*p++);x+=c;y-=c; + c=*(cp-*p++);x+=2*c;y-=c; + c=*(cp-*p);x+=3*c;y-=c; + p+=x_size-6; + + c=*(cp-*p++);x-=3*c; + c=*(cp-*p++);x-=2*c; + c=*(cp-*p);x-=c; + p+=2; + c=*(cp-*p++);x+=c; + c=*(cp-*p++);x+=2*c; + c=*(cp-*p);x+=3*c; + p+=x_size-6; + + c=*(cp-*p++);x-=3*c;y+=c; + c=*(cp-*p++);x-=2*c;y+=c; + c=*(cp-*p++);x-=c;y+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p++);x+=c;y+=c; + c=*(cp-*p++);x+=2*c;y+=c; + c=*(cp-*p);x+=3*c;y+=c; + p+=x_size-5; + + c=*(cp-*p++);x-=2*c;y+=2*c; + c=*(cp-*p++);x-=c;y+=2*c; + c=*(cp-*p++);y+=2*c; + c=*(cp-*p++);x+=c;y+=2*c; + c=*(cp-*p);x+=2*c;y+=2*c; + p+=x_size-3; + + c=*(cp-*p++);x-=c;y+=3*c; + c=*(cp-*p++);y+=3*c; + c=*(cp-*p);x+=c;y+=3*c; + + z = susan_sqrtf((float)((x*x) + (y*y))); + if (z > (0.9*(float)n)) { /* 0.5 */ + do_symmetry=0; + if (x==0) + z=1000000.0; + else + z=((float)y) / ((float)x); + if (z < 0) { z=-z; w=-1; } + else w=1; + if (z < 0.5) { /* vert_edge */ a=0; b=1; } + else { if (z > 2.0) { /* hor_edge */ a=1; b=0; } + else { /* diag_edge */ if (w>0) { a=1; b=1; } + else { a=-1; b=1; }}} + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) && + (m > r[(i+(2*a))*x_size+j+(2*b)]) && (m >= r[(i-(2*a))*x_size+j-(2*b)]) ) + mid[i*x_size+j] = 1; + } else { + do_symmetry=1; + } + } else { + do_symmetry=1; + } + + if (do_symmetry==1) { + p=in + (i-3)*x_size + j - 1; + x=0; y=0; w=0; + + /* | \ + y -x- w + | \ */ + + c=*(cp-*p++);x+=c;y+=9*c;w+=3*c; + c=*(cp-*p++);y+=9*c; + c=*(cp-*p);x+=c;y+=9*c;w-=3*c; + p+=x_size-3; + + c=*(cp-*p++);x+=4*c;y+=4*c;w+=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w+=2*c; + c=*(cp-*p++);y+=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w-=2*c; + c=*(cp-*p);x+=4*c;y+=4*c;w-=4*c; + p+=x_size-5; + + c=*(cp-*p++);x+=9*c;y+=c;w+=3*c; + c=*(cp-*p++);x+=4*c;y+=c;w+=2*c; + c=*(cp-*p++);x+=c;y+=c;w+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p++);x+=c;y+=c;w-=c; + c=*(cp-*p++);x+=4*c;y+=c;w-=2*c; + c=*(cp-*p);x+=9*c;y+=c;w-=3*c; + p+=x_size-6; + + c=*(cp-*p++);x+=9*c; + c=*(cp-*p++);x+=4*c; + c=*(cp-*p);x+=c; + p+=2; + c=*(cp-*p++);x+=c; + c=*(cp-*p++);x+=4*c; + c=*(cp-*p);x+=9*c; + p+=x_size-6; + + c=*(cp-*p++);x+=9*c;y+=c;w-=3*c; + c=*(cp-*p++);x+=4*c;y+=c;w-=2*c; + c=*(cp-*p++);x+=c;y+=c;w-=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p++);x+=c;y+=c;w+=c; + c=*(cp-*p++);x+=4*c;y+=c;w+=2*c; + c=*(cp-*p);x+=9*c;y+=c;w+=3*c; + p+=x_size-5; + + c=*(cp-*p++);x+=4*c;y+=4*c;w-=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w-=2*c; + c=*(cp-*p++);y+=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w+=2*c; + c=*(cp-*p);x+=4*c;y+=4*c;w+=4*c; + p+=x_size-3; + + c=*(cp-*p++);x+=c;y+=9*c;w-=3*c; + c=*(cp-*p++);y+=9*c; + c=*(cp-*p);x+=c;y+=9*c;w+=3*c; + + if (y==0) + z = 1000000.0; + else + z = ((float)x) / ((float)y); + if (z < 0.5) { /* vertical */ a=0; b=1; } + else { if (z > 2.0) { /* horizontal */ a=1; b=0; } + else { /* diagonal */ if (w>0) { a=-1; b=1; } + else { a=1; b=1; }}} + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) && + (m > r[(i+(2*a))*x_size+j+(2*b)]) && (m >= r[(i-(2*a))*x_size+j-(2*b)]) ) + mid[i*x_size+j] = 2; + } + } + } + } +} + + +void susan_edges_small( uchar *in, char *r, uchar *mid, uchar *bp, + int max_no, int x_size, int y_size ) +{ + float z; + int do_symmetry, i, j, m, n, a, b, x, y, w; + uchar c,*p,*cp; + + susan_wccmemset(r,0,x_size * y_size); + + _Pragma( "loopbound min 0 max 0" ) + for (i=1;i0) { + m=r[i*x_size+j]; + n=max_no - m; + cp=bp + in[i*x_size+j]; + + if (n>250) { + p=in + (i-1)*x_size + j - 1; + x=0;y=0; + + c=*(cp-*p++);x-=c;y-=c; + c=*(cp-*p++);y-=c; + c=*(cp-*p);x+=c;y-=c; + p+=x_size-2; + + c=*(cp-*p);x-=c; + p+=2; + c=*(cp-*p);x+=c; + p+=x_size-2; + + c=*(cp-*p++);x-=c;y+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p);x+=c;y+=c; + + z = susan_sqrtf((float)((x*x) + (y*y))); + if (z > (0.4*(float)n)) { /* 0.6 */ + do_symmetry=0; + if (x==0) + z=1000000.0; + else + z=((float)y) / ((float)x); + if (z < 0) { z=-z; w=-1; } + else w=1; + if (z < 0.5) { /* vert_edge */ a=0; b=1; } + else { if (z > 2.0) { /* hor_edge */ a=1; b=0; } + else { /* diag_edge */ if (w>0) { a=1; b=1; } + else { a=-1; b=1; } + } + } + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) ) { + mid[i*x_size+j] = 1; + } + } else { + do_symmetry=1; + } + } else { + do_symmetry=1; + } + + if (do_symmetry==1) { + p=in + (i-1)*x_size + j - 1; + x=0; y=0; w=0; + + /* | \ + y -x- w + | \ */ + + c=*(cp-*p++);x+=c;y+=c;w+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p);x+=c;y+=c;w-=c; + p+=x_size-2; + + c=*(cp-*p);x+=c; + p+=2; + c=*(cp-*p);x+=c; + p+=x_size-2; + + c=*(cp-*p++);x+=c;y+=c;w-=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p);x+=c;y+=c;w+=c; + + if (y==0) + z = 1000000.0; + else + z = ((float)x) / ((float)y); + if (z < 0.5) { /* vertical */ a=0; b=1; } + else { if (z > 2.0) { /* horizontal */ a=1; b=0; } + else { /* diagonal */ if (w>0) { a=-1; b=1; } + else { a=1; b=1; } + } + } + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) ) { + mid[i*x_size+j] = 2; + } + } + } + } + } +} + + +void susan_corner_draw( uchar *in, CORNER_LIST corner_list, + int x_size, int drawing_mode) +{ + uchar *p; + int n=0; + + _Pragma( "loopbound min 0 max 0" ) + while(corner_list[n].info != 7) { + if (drawing_mode==0) { + p = in + (corner_list[n].y-1)*x_size + corner_list[n].x - 1; + *p++=255; *p++=255; *p=255; p+=x_size-2; + *p++=255; *p++=0; *p=255; p+=x_size-2; + *p++=255; *p++=255; *p=255; + n++; + } else { + p = in + corner_list[n].y*x_size + corner_list[n].x; + *p=0; + n++; + } + } +} + + +void susan_corners( uchar *in, char *r, uchar *bp, + int max_no, CORNER_LIST corner_list, int x_size, int y_size) +{ + int n,x,y,sq,xx,yy, + i,j; + float divide; + uchar c,*p,*cp; + char *cgx,*cgy; + + susan_wccmemset(r,0,x_size * y_size); + + cgx=(char *)susan_wccmalloc(x_size*y_size); + cgy=(char *)susan_wccmalloc(x_size*y_size); + + _Pragma( "loopbound min 85 max 85" ) + for (i=5;i ((n*n)/2) ) { + if(yy290){ + r[i*x_size+j] = max_no-n; + cgx[i*x_size+j] = (51*x)/n; + cgy[i*x_size+j] = (51*y)/n; + } + } + } + }}}}}}}}}}}}}}}}}} + } + } + + /* to locate the local maxima */ + n=0; + _Pragma( "loopbound min 85 max 85" ) + for (i=5;i0) { + /* 5x5 mask */ + #ifdef FIVE_SUPP + if ((x>r[(i-1)*x_size+j+2]) && + (x>r[(i )*x_size+j+1]) && + (x>r[(i )*x_size+j+2]) && + (x>r[(i+1)*x_size+j-1]) && + (x>r[(i+1)*x_size+j ]) && + (x>r[(i+1)*x_size+j+1]) && + (x>r[(i+1)*x_size+j+2]) && + (x>r[(i+2)*x_size+j-2]) && + (x>r[(i+2)*x_size+j-1]) && + (x>r[(i+2)*x_size+j ]) && + (x>r[(i+2)*x_size+j+1]) && + (x>r[(i+2)*x_size+j+2]) && + (x>=r[(i-2)*x_size+j-2]) && + (x>=r[(i-2)*x_size+j-1]) && + (x>=r[(i-2)*x_size+j ]) && + (x>=r[(i-2)*x_size+j+1]) && + (x>=r[(i-2)*x_size+j+2]) && + (x>=r[(i-1)*x_size+j-2]) && + (x>=r[(i-1)*x_size+j-1]) && + (x>=r[(i-1)*x_size+j ]) && + (x>=r[(i-1)*x_size+j+1]) && + (x>=r[(i )*x_size+j-2]) && + (x>=r[(i )*x_size+j-1]) && + (x>=r[(i+1)*x_size+j-2]) ) + #endif + #ifdef SEVEN_SUPP + if ((x>r[(i-3)*x_size+j-3]) && + (x>r[(i-3)*x_size+j-2]) && + (x>r[(i-3)*x_size+j-1]) && + (x>r[(i-3)*x_size+j ]) && + (x>r[(i-3)*x_size+j+1]) && + (x>r[(i-3)*x_size+j+2]) && + (x>r[(i-3)*x_size+j+3]) && + + (x>r[(i-2)*x_size+j-3]) && + (x>r[(i-2)*x_size+j-2]) && + (x>r[(i-2)*x_size+j-1]) && + (x>r[(i-2)*x_size+j ]) && + (x>r[(i-2)*x_size+j+1]) && + (x>r[(i-2)*x_size+j+2]) && + (x>r[(i-2)*x_size+j+3]) && + + (x>r[(i-1)*x_size+j-3]) && + (x>r[(i-1)*x_size+j-2]) && + (x>r[(i-1)*x_size+j-1]) && + (x>r[(i-1)*x_size+j ]) && + (x>r[(i-1)*x_size+j+1]) && + (x>r[(i-1)*x_size+j+2]) && + (x>r[(i-1)*x_size+j+3]) && + + (x>r[(i)*x_size+j-3]) && + (x>r[(i)*x_size+j-2]) && + (x>r[(i)*x_size+j-1]) && + (x>=r[(i)*x_size+j+1]) && + (x>=r[(i)*x_size+j+2]) && + (x>=r[(i)*x_size+j+3]) && + + (x>=r[(i+1)*x_size+j-3]) && + (x>=r[(i+1)*x_size+j-2]) && + (x>=r[(i+1)*x_size+j-1]) && + (x>=r[(i+1)*x_size+j ]) && + (x>=r[(i+1)*x_size+j+1]) && + (x>=r[(i+1)*x_size+j+2]) && + (x>=r[(i+1)*x_size+j+3]) && + + (x>=r[(i+2)*x_size+j-3]) && + (x>=r[(i+2)*x_size+j-2]) && + (x>=r[(i+2)*x_size+j-1]) && + (x>=r[(i+2)*x_size+j ]) && + (x>=r[(i+2)*x_size+j+1]) && + (x>=r[(i+2)*x_size+j+2]) && + (x>=r[(i+2)*x_size+j+3]) && + + (x>=r[(i+3)*x_size+j-3]) && + (x>=r[(i+3)*x_size+j-2]) && + (x>=r[(i+3)*x_size+j-1]) && + (x>=r[(i+3)*x_size+j ]) && + (x>=r[(i+3)*x_size+j+1]) && + (x>=r[(i+3)*x_size+j+2]) && + (x>=r[(i+3)*x_size+j+3]) ) + #endif + { + corner_list[n].info=0; + corner_list[n].x=j; + corner_list[n].y=i; + corner_list[n].dx=cgx[i*x_size+j]; + corner_list[n].dy=cgy[i*x_size+j]; + corner_list[n].I=in[i*x_size+j]; + n++; + if(n==MAX_CORNERS){ + /* "Too many corners." */ + } + } + } + } + } + corner_list[n].info=7; +} + + +void susan_corners_quick( uchar *in, char *r, uchar *bp, + int max_no, CORNER_LIST corner_list, int x_size, int y_size ) +{ + int n,x,y,i,j; + uchar *p,*cp; + + susan_wccmemset(r,0,x_size * y_size); + + _Pragma( "loopbound min 0 max 0" ) + for (i=7;i0) { + /* 5x5 mask */ + #ifdef FIVE_SUPP + if ((x>r[(i-1)*x_size+j+2]) && + (x>r[(i )*x_size+j+1]) && + (x>r[(i )*x_size+j+2]) && + (x>r[(i+1)*x_size+j-1]) && + (x>r[(i+1)*x_size+j ]) && + (x>r[(i+1)*x_size+j+1]) && + (x>r[(i+1)*x_size+j+2]) && + (x>r[(i+2)*x_size+j-2]) && + (x>r[(i+2)*x_size+j-1]) && + (x>r[(i+2)*x_size+j ]) && + (x>r[(i+2)*x_size+j+1]) && + (x>r[(i+2)*x_size+j+2]) && + (x>=r[(i-2)*x_size+j-2]) && + (x>=r[(i-2)*x_size+j-1]) && + (x>=r[(i-2)*x_size+j ]) && + (x>=r[(i-2)*x_size+j+1]) && + (x>=r[(i-2)*x_size+j+2]) && + (x>=r[(i-1)*x_size+j-2]) && + (x>=r[(i-1)*x_size+j-1]) && + (x>=r[(i-1)*x_size+j ]) && + (x>=r[(i-1)*x_size+j+1]) && + (x>=r[(i )*x_size+j-2]) && + (x>=r[(i )*x_size+j-1]) && + (x>=r[(i+1)*x_size+j-2]) ) + #endif + #ifdef SEVEN_SUPP + if ((x>r[(i-3)*x_size+j-3]) && + (x>r[(i-3)*x_size+j-2]) && + (x>r[(i-3)*x_size+j-1]) && + (x>r[(i-3)*x_size+j ]) && + (x>r[(i-3)*x_size+j+1]) && + (x>r[(i-3)*x_size+j+2]) && + (x>r[(i-3)*x_size+j+3]) && + + (x>r[(i-2)*x_size+j-3]) && + (x>r[(i-2)*x_size+j-2]) && + (x>r[(i-2)*x_size+j-1]) && + (x>r[(i-2)*x_size+j ]) && + (x>r[(i-2)*x_size+j+1]) && + (x>r[(i-2)*x_size+j+2]) && + (x>r[(i-2)*x_size+j+3]) && + + (x>r[(i-1)*x_size+j-3]) && + (x>r[(i-1)*x_size+j-2]) && + (x>r[(i-1)*x_size+j-1]) && + (x>r[(i-1)*x_size+j ]) && + (x>r[(i-1)*x_size+j+1]) && + (x>r[(i-1)*x_size+j+2]) && + (x>r[(i-1)*x_size+j+3]) && + + (x>r[(i)*x_size+j-3]) && + (x>r[(i)*x_size+j-2]) && + (x>r[(i)*x_size+j-1]) && + (x>=r[(i)*x_size+j+1]) && + (x>=r[(i)*x_size+j+2]) && + (x>=r[(i)*x_size+j+3]) && + + (x>=r[(i+1)*x_size+j-3]) && + (x>=r[(i+1)*x_size+j-2]) && + (x>=r[(i+1)*x_size+j-1]) && + (x>=r[(i+1)*x_size+j ]) && + (x>=r[(i+1)*x_size+j+1]) && + (x>=r[(i+1)*x_size+j+2]) && + (x>=r[(i+1)*x_size+j+3]) && + + (x>=r[(i+2)*x_size+j-3]) && + (x>=r[(i+2)*x_size+j-2]) && + (x>=r[(i+2)*x_size+j-1]) && + (x>=r[(i+2)*x_size+j ]) && + (x>=r[(i+2)*x_size+j+1]) && + (x>=r[(i+2)*x_size+j+2]) && + (x>=r[(i+2)*x_size+j+3]) && + + (x>=r[(i+3)*x_size+j-3]) && + (x>=r[(i+3)*x_size+j-2]) && + (x>=r[(i+3)*x_size+j-1]) && + (x>=r[(i+3)*x_size+j ]) && + (x>=r[(i+3)*x_size+j+1]) && + (x>=r[(i+3)*x_size+j+2]) && + (x>=r[(i+3)*x_size+j+3]) ) + #endif + { + corner_list[n].info=0; + corner_list[n].x=j; + corner_list[n].y=i; + x = in[(i-2)*x_size+j-2] + in[(i-2)*x_size+j-1] + in[(i-2)*x_size+j] + in[(i-2)*x_size+j+1] + in[(i-2)*x_size+j+2] + + in[(i-1)*x_size+j-2] + in[(i-1)*x_size+j-1] + in[(i-1)*x_size+j] + in[(i-1)*x_size+j+1] + in[(i-1)*x_size+j+2] + + in[(i )*x_size+j-2] + in[(i )*x_size+j-1] + in[(i )*x_size+j] + in[(i )*x_size+j+1] + in[(i )*x_size+j+2] + + in[(i+1)*x_size+j-2] + in[(i+1)*x_size+j-1] + in[(i+1)*x_size+j] + in[(i+1)*x_size+j+1] + in[(i+1)*x_size+j+2] + + in[(i+2)*x_size+j-2] + in[(i+2)*x_size+j-1] + in[(i+2)*x_size+j] + in[(i+2)*x_size+j+1] + in[(i+2)*x_size+j+2]; + + corner_list[n].I=x/25; + /*corner_list[n].I=in[i*x_size+j];*/ + x = in[(i-2)*x_size+j+2] + in[(i-1)*x_size+j+2] + in[(i)*x_size+j+2] + in[(i+1)*x_size+j+2] + in[(i+2)*x_size+j+2] - + (in[(i-2)*x_size+j-2] + in[(i-1)*x_size+j-2] + in[(i)*x_size+j-2] + in[(i+1)*x_size+j-2] + in[(i+2)*x_size+j-2]); + x += x + in[(i-2)*x_size+j+1] + in[(i-1)*x_size+j+1] + in[(i)*x_size+j+1] + in[(i+1)*x_size+j+1] + in[(i+2)*x_size+j+1] - + (in[(i-2)*x_size+j-1] + in[(i-1)*x_size+j-1] + in[(i)*x_size+j-1] + in[(i+1)*x_size+j-1] + in[(i+2)*x_size+j-1]); + + y = in[(i+2)*x_size+j-2] + in[(i+2)*x_size+j-1] + in[(i+2)*x_size+j] + in[(i+2)*x_size+j+1] + in[(i+2)*x_size+j+2] - + (in[(i-2)*x_size+j-2] + in[(i-2)*x_size+j-1] + in[(i-2)*x_size+j] + in[(i-2)*x_size+j+1] + in[(i-2)*x_size+j+2]); + y += y + in[(i+1)*x_size+j-2] + in[(i+1)*x_size+j-1] + in[(i+1)*x_size+j] + in[(i+1)*x_size+j+1] + in[(i+1)*x_size+j+2] - + (in[(i-1)*x_size+j-2] + in[(i-1)*x_size+j-1] + in[(i-1)*x_size+j] + in[(i-1)*x_size+j+1] + in[(i-1)*x_size+j+2]); + corner_list[n].dx=x/15; + corner_list[n].dy=y/15; + n++; + if(n==MAX_CORNERS){ + /* "Too many corners." */ + } + } + } + } + } + corner_list[n].info=7; +} + + +void susan_call_susan( struct wccFILE *inputFile, int mode ) +{ + uchar *in, *bp, *mid; + int x_size, y_size; + char *r; + CORNER_LIST corner_list; + + susan_get_image( inputFile, &in, &x_size, &y_size ); + + if (susan_dt<0) susan_three_by_three=1; + if ( (susan_principle_conf==1) && (mode==0) ) + mode=1; + + switch (mode) { + case 0: + /* {{{ smoothing */ + + susan_setup_brightness_lut(&bp,susan_bt,2); + susan_smoothing(susan_three_by_three,in,susan_dt,x_size,y_size,bp); + + break; + case 1: + /* {{{ edges */ + + r = (char *) susan_wccmalloc(x_size * y_size); + susan_setup_brightness_lut(&bp,susan_bt,6); + + if (susan_principle_conf) { + if (susan_three_by_three) + susan_principle_small(in,r,bp,susan_max_no_edges,x_size,y_size); + else + susan_principle(in,r,bp,susan_max_no_edges,x_size,y_size); + susan_int_to_uchar(r,in,x_size*y_size); + } else { + mid = (uchar *)susan_wccmalloc(x_size*y_size); + susan_wccmemset(mid,100,x_size * y_size); /* note not set to zero */ + + if (susan_three_by_three) + susan_edges_small(in,r,mid,bp,susan_max_no_edges,x_size,y_size); + else + susan_edges(in,r,mid,bp,susan_max_no_edges,x_size,y_size); + if(susan_thin_post_proc) + susan_thin(r,mid,x_size,y_size); + susan_edge_draw(in,mid,x_size,y_size,susan_drawing_mode); + } + + break; + case 2: + /* {{{ corners */ + + r = (char *) susan_wccmalloc(x_size * y_size); + susan_setup_brightness_lut(&bp,susan_bt,6); + + if (susan_principle_conf) { + susan_principle(in,r,bp,susan_max_no_corners,x_size,y_size); + susan_int_to_uchar(r,in,x_size*y_size); + } else { + if(susan_susan_quick) + susan_corners_quick(in,r,bp,susan_max_no_corners,corner_list,x_size,y_size); + else + susan_corners(in,r,bp,susan_max_no_corners,corner_list,x_size,y_size); + susan_corner_draw(in,corner_list,x_size,susan_drawing_mode); + } + + break; + } + + susan_put_image(x_size,y_size); +} + +void susan_init( void ) +{ + volatile int a = 0; + susan_file.data = susan_input; + susan_file.size = 7292; + susan_file.size += a; + susan_file.cur_pos = 0; + susan_file.cur_pos += a; + + susan_dt = 4.0; + susan_dt += a; + susan_bt = 20; + susan_bt += a; + susan_principle_conf = 0; + susan_principle_conf += a; + susan_thin_post_proc = 1; + susan_thin_post_proc += a; + susan_three_by_three = 0; + susan_three_by_three += a; + susan_drawing_mode = 0; + susan_drawing_mode += a; + susan_susan_quick = 0; + susan_susan_quick += a; + susan_max_no_corners = 50; + susan_max_no_corners += a; + susan_max_no_edges = 50; + susan_max_no_edges += a; + + // mode=0; /* Smoothing mode */ + // mode=1; /* Edges mode */ + // mode=2; /* Corners mode */ + + // principle=1; /* Output initial enhancement image only; corners or edges mode (default is edges mode) */ + // thin_post_proc=0; /* No post-processing on the binary edge map (runs much faster); edges mode */ + // drawing_mode=1; /* Mark corners/edges with single black points instead of black with white border; corners or edges mode */ + // three_by_three=1; /* Use flat 3x3 mask, edges or smoothing mode */ + // susan_quick=1; /* Use faster (and usually stabler) corner mode; edge-like corner suppression not carried out; corners mode */ + // dt=10.0; /* Distance threshold, smoothing mode, (default=4) */ + // bt=50; /* Brightness threshold, all modes, (default=20) */ +} + +void susan_main( void ) +{ + susan_call_susan( &susan_file, 0 ); + susan_wccfreeall(); + susan_call_susan( &susan_file, 1 ); + susan_wccfreeall(); + susan_call_susan( &susan_file, 2 ); + susan_wccfreeall(); +} + +int susan_return( void ) +{ + return 0; +} + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsCompletecur_pos, i2 = 0; + size_x number_of_chars_to_read = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 7220 max 7220" ) + while (i < stream->cur_pos + number_of_chars_to_read) { + ((unsigned char*)ptr)[i2++] = stream->data[i++]; + } + stream->cur_pos += number_of_chars_to_read; + return number_of_chars_to_read; +} + +int susan_wccfgetc(struct wccFILE *stream) +{ + if ( susan_wccfeof( stream ) ) { + return EOFX; + } else { + return stream->data[stream->cur_pos++]; + } +} + +char *susan_wccfgets(char *str, int num, struct wccFILE *stream ) +{ + if ( !stream || susan_wccfeof( stream ) || !str || num <= 0 ) { + return 0; + } + + int pos = 0; + _Pragma( "loopbound min 58 max 58" ) + while ( pos < num - 1 && !susan_wccfeof( stream ) ) { + str[pos] = stream->data[stream->cur_pos]; + if ( str[pos] == '\n' ) { + break; + } + + stream->cur_pos++; + pos++; + } + str[pos++] = '\0'; + + return str; +} + +int susan_wccfseek(struct wccFILE* stream, long int offset, enum _Origin_ origin) +{ + if (origin == WCCSEEK_SET) { + stream->cur_pos = offset; + return 0; + } else if (origin == WCCSEEK_CUR) { + stream->cur_pos += offset; + return 0; + } else if (origin == WCCSEEK_END) { + stream->cur_pos = stream->size + offset; + return 0; + } + return -1; +} + + +int susan_wccfgetpos(struct wccFILE* stream, unsigned* position) +{ + *position = stream->cur_pos; + return 0; +} + + +int susan_wccfeof(struct wccFILE* stream) +{ + return stream->cur_pos == stream->size ? 1 : 0; +} diff --git a/all_pairs/source/susan/wccfile.h b/all_pairs/source/susan/wccfile.h new file mode 100644 index 0000000..9314361 --- /dev/null +++ b/all_pairs/source/susan/wccfile.h @@ -0,0 +1,24 @@ +#ifndef WCC_FILE_H +#define WCC_FILE_H + +enum _Origin_ { WCCSEEK_SET, WCCSEEK_CUR, WCCSEEK_END }; +typedef enum _Origin_ Origin; +typedef unsigned int size_x; + +#define EOFX -1 + +struct wccFILE { + char* data; + size_x size; + unsigned cur_pos; +}; + +size_x susan_wccfread (void* ptr, size_x size, size_x count, struct wccFILE* stream); +int susan_wccfseek (struct wccFILE* stream, long int offset, Origin origin); +int susan_wccfgetpos (struct wccFILE* stream, unsigned* position); +int susan_wccfeof (struct wccFILE* stream); +int susan_wccfgetc (struct wccFILE *stream); +char *susan_wccfgets (char *str, int num, struct wccFILE *stream ); + +#endif + diff --git a/all_pairs/source/susan/wcclibm.c b/all_pairs/source/susan/wcclibm.c new file mode 100644 index 0000000..bca8907 --- /dev/null +++ b/all_pairs/source/susan/wcclibm.c @@ -0,0 +1,444 @@ +#include "math_private.h" +#include "wcclibm.h" + + + +/* e_rem_pio2f.c -- float version of e_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_rem_pio2f.c,v 1.5 1995/05/10 20:46:03 jtc Exp $"; +#endif + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2f() + */ + +/* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ +static const int32_t susan_npio2_hw[] = { +0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, +0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, +0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, +0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, +0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, +0x4242c700, 0x42490f00 +}; + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +static const float +/* zero = 0.0000000000e+00f, /\* 0x00000000 *\/ */ +/* half = 5.0000000000e-01f, /\* 0x3f000000 *\/ */ +/* two8 = 2.5600000000e+02f, /\* 0x43800000 *\/ */ +susan_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ +susan_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ +susan_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ +susan_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ +susan_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ +susan_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ +susan_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + +int32_t susan___ieee754_rem_pio2f(float x, float *y) +{ + float z,w,t,r,fn; + int32_t i,j,n,ix,hx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - susan_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - susan_pio2_1t; + y[1] = (z-y[0])-susan_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= susan_pio2_2; + y[0] = z - susan_pio2_2t; + y[1] = (z-y[0])-susan_pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + susan_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + susan_pio2_1t; + y[1] = (z-y[0])+susan_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += susan_pio2_2; + y[0] = z + susan_pio2_2t; + y[1] = (z-y[0])+susan_pio2_2t; + } + return -1; + } + } + if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (int32_t) (t*susan_invpio2+susan_half); + fn = (float)n; + r = t-fn*susan_pio2_1; + w = fn*susan_pio2_1t; /* 1st round good to 40 bit */ + if(n<32&&(int32_t)(ix&0xffffff00)!=susan_npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix>>23; + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*susan_pio2_2; + r = t-w; + w = fn*susan_pio2_2t-((t-r)-w); + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*susan_pio2_3; + r = t-w; + w = fn*susan_pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7f800000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + + y[0]=y[1]=x-x; return 0; /* dummy initialisation */ + return 0; /* doesn't happen for our input */ +} + +/* k_cosf.c -- float version of k_cos.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_cosf.c,v 1.4 1995/05/10 20:46:23 jtc Exp $"; +#endif + + +static const float +/* one = 1.0000000000e+00, /\* 0x3f800000 *\/ */ +susan_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ +susan_C2 = -1.3888889225e-03f, /* 0xbab60b61 */ +susan_C3 = 2.4801587642e-05f, /* 0x37d00d01 */ +susan_C4 = -2.7557314297e-07f, /* 0xb493f27c */ +susan_C5 = 2.0875723372e-09f, /* 0x310f74f6 */ +susan_C6 = -1.1359647598e-11f; /* 0xad47d74e */ + +float susan___kernel_cosf(float x, float y) +{ + float a,hz,z,r,qx; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x32000000) { /* if x < 2**27 */ + if(((int)x)==0) return susan_one; /* generate inexact */ + } + z = x*x; + r = z*(susan_C1+z*(susan_C2+z*(susan_C3+z*(susan_C4+z*(susan_C5+z*susan_C6))))); + if(ix < 0x3e99999a) /* if |x| < 0.3 */ + return susan_one - ((float)0.5f*z - (z*r - x*y)); + else { + if(ix > 0x3f480000) { /* x > 0.78125 */ + qx = (float)0.28125f; + } else { + SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ + } + hz = (float)0.5f*z-qx; + a = susan_one-qx; + return a - (hz - (z*r-x*y)); + } +} + +/* k_sinf.c -- float version of k_sin.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4 1995/05/10 20:46:33 jtc Exp $"; +#endif + + +static const float +/* half = 5.0000000000e-01f,/\* 0x3f000000 *\/ */ +susan_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ +susan_S2 = 8.3333337680e-03f, /* 0x3c088889 */ +susan_S3 = -1.9841270114e-04f, /* 0xb9500d01 */ +susan_S4 = 2.7557314297e-06f, /* 0x3638ef1b */ +susan_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ +susan_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ + +float susan___kernel_sinf(float x, float y, int iy) +{ + float z,r,v; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x32000000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = susan_S2+z*(susan_S3+z*(susan_S4+z*(susan_S5+z*susan_S6))); + if(iy==0) return x+v*(susan_S1+z*r); + else return x-((z*(susan_half*y-v*r)-y)-v*susan_S1); +} +/* s_atanf.c -- float version of s_atan.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_atanf.c,v 1.4 1995/05/10 20:46:47 jtc Exp $"; +#endif + + +static const float susan_atanhi[] = { + 4.6364760399e-01f, /* atan(0.5)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ +}; + +static const float susan_atanlo[] = { + 5.0121582440e-09f, /* atan(0.5)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ +}; + +static const float susan_aT[] = { + 3.3333334327e-01f, /* 0x3eaaaaaa */ + -2.0000000298e-01f, /* 0xbe4ccccd */ + 1.4285714924e-01f, /* 0x3e124925 */ + -1.1111110449e-01f, /* 0xbde38e38 */ + 9.0908870101e-02f, /* 0x3dba2e6e */ + -7.6918758452e-02f, /* 0xbd9d8795 */ + 6.6610731184e-02f, /* 0x3d886b35 */ + -5.8335702866e-02f, /* 0xbd6ef16b */ + 4.9768779427e-02f, /* 0x3d4bda59 */ + -3.6531571299e-02f, /* 0xbd15a221 */ + 1.6285819933e-02f, /* 0x3c8569d7 */ +}; + +float susan___atanf(float x) +{ + float w,s1,s2,z; + int32_t ix,hx,id; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x50800000) { /* if |x| >= 2^34 */ + if(ix>0x7f800000) + return x+x; /* NaN */ + if(hx>0) return susan_atanhi[3]+susan_atanlo[3]; + else return -susan_atanhi[3]-susan_atanlo[3]; + } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ + if (ix < 0x31000000) { /* |x| < 2^-29 */ + if(susan_huge+x>susan_one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsf(x); + if (ix < 0x3f980000) { /* |x| < 1.1875 */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = ((float)2.0f*x-susan_one)/((float)2.0f+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-susan_one)/(x+susan_one); + } + } else { + if (ix < 0x401c0000) { /* |x| < 2.4375 */ + id = 2; x = (x-(float)1.5f)/(susan_one+(float)1.5f*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -(float)1.0f/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(susan_aT[0]+w*(susan_aT[2]+w*(susan_aT[4]+w*(susan_aT[6]+w*(susan_aT[8]+w*susan_aT[10]))))); + s2 = w*(susan_aT[1]+w*(susan_aT[3]+w*(susan_aT[5]+w*(susan_aT[7]+w*susan_aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = susan_atanhi[id] - ((x*(s1+s2) - susan_atanlo[id]) - x); + return (hx<0)? -z:z; + } +} + +/* s_cosf.c -- float version of s_cos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +float susan___cosf(float x) +{ + float y[2],z=0.0f; + int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return susan___kernel_cosf(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = susan___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return susan___kernel_cosf(y[0],y[1]); + case 1: return -susan___kernel_sinf(y[0],y[1],1); + case 2: return -susan___kernel_cosf(y[0],y[1]); + default: + return susan___kernel_sinf(y[0],y[1],1); + } + } +} + +/* s_sinf.c -- float version of s_sin.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +float susan___sinf(float x) +{ + float y[2],z=0.0; + int32_t n, ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return susan___kernel_sinf(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = susan___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return susan___kernel_sinf(y[0],y[1],1); + case 1: return susan___kernel_cosf(y[0],y[1]); + case 2: return -susan___kernel_sinf(y[0],y[1],1); + default: + return -susan___kernel_cosf(y[0],y[1]); + } + } +} + +/* s_fabsf.c -- float version of s_fabs.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabsf(x) returns the absolute value of x. + */ + + +float susan___fabsf(float x) +{ + u_int32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} diff --git a/all_pairs/source/susan/wcclibm.h b/all_pairs/source/susan/wcclibm.h new file mode 100644 index 0000000..bcf4c65 --- /dev/null +++ b/all_pairs/source/susan/wcclibm.h @@ -0,0 +1,53 @@ +#ifndef _WCCLIBM +#define _WCCLIBM + +#define int32_t int +#define uint32_t unsigned int +#define u_int16_t unsigned short +#define u_int32_t unsigned int + +// Often used variables/consts +#ifdef __STDC__ +static const float +#else +static float +#endif +susan_one = 1.0f, +susan_half = 5.0000000000e-01f, /* 0x3f000000 */ +susan_zero = 0.0f, +susan_huge = 1.0e30, +susan_two8 = 2.5600000000e+02f, /* 0x43800000 */ +susan_twon8 = 3.9062500000e-03f; /* 0x3b800000 */ + +// The following defines map the math functions to specialized calls +#define acos susan___ieee754_acosf +#define atan susan___atanf +#define cos susan___cosf +#define fabs susan___fabsf +#define fabsf susan___fabsf +#define isinf susan___isinff +#define pow susan___ieee754_powf +#define sqrt susan___ieee754_sqrtf +#define log10 susan___ieee754_log10f +#define log susan___ieee754_logf +#define sin susan___sinf + +float susan___atanf(float x); +float susan___copysignf(float x, float y); +float susan___cosf(float x); +float susan___fabsf(float x); +float susan___floorf(float x); +float susan___ieee754_acosf(float x); +float susan___ieee754_powf(float x, float y); +int32_t susan___ieee754_rem_pio2f(float x, float *y); +float susan___ieee754_sqrtf(float x); +int susan___isinff (float x); +float susan___kernel_cosf(float x, float y); +float susan___kernel_sinf(float x, float y, int iy); +int susan___kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2); +float susan___scalbnf (float x, int n); +float susan___ieee754_logf(float x); +float susan___ieee754_log10f(float x); +float susan___sinf(float x); + +#endif // _WCCLIBM diff --git a/all_pairs/source/susan/wccmalloc.c b/all_pairs/source/susan/wccmalloc.c new file mode 100644 index 0000000..edf01cc --- /dev/null +++ b/all_pairs/source/susan/wccmalloc.c @@ -0,0 +1,51 @@ +#include "wccmalloc.h" + +// This must be redefined for each new benchmark +#define HEAP_SIZE 30000 + +char susan_simulated_heap[HEAP_SIZE]; +unsigned int susan_freeHeapPos; + +void* susan_wccmalloc( unsigned int numberOfBytes ) +{ + // Get a 4-byte adress for alignment purposes + unsigned int offset = ( (unsigned long)susan_simulated_heap + susan_freeHeapPos ) % 4; + if ( offset ) { + susan_freeHeapPos += 4 - offset; + } + void* currentPos = (void*)&susan_simulated_heap[susan_freeHeapPos]; + susan_freeHeapPos += numberOfBytes; + return currentPos; +} +void susan_wccfreeall( void ) +{ + susan_freeHeapPos = 0; +} + +void* susan_wccmemcpy(void* dstpp, const void* srcpp, unsigned int len) +{ + unsigned long int dstp = (long int) dstpp; + unsigned long int srcp = (long int) srcpp; + + _Pragma("loopbound min 76 max 76") + while (len > 0) { + char __x = ((char *) srcp)[0]; + srcp += 1; + len -= 1; + ((char *) dstp)[0] = __x; + dstp += 1; + } + + return dstpp; +} + +void susan_wccmemset( void *p, int value, unsigned int num ) +{ + unsigned long i; + char *char_ptr = (char*)p; + + _Pragma( "loopbound min 7220 max 28880" ) + for ( i = 0; i < num; ++i ) { + *char_ptr++ = (unsigned char)value; + } +} diff --git a/all_pairs/source/susan/wccmalloc.h b/all_pairs/source/susan/wccmalloc.h new file mode 100644 index 0000000..dbb2ada --- /dev/null +++ b/all_pairs/source/susan/wccmalloc.h @@ -0,0 +1,10 @@ +#ifndef _WCCMALLOC_H +#define _WCCMALLOC_H + +void* susan_wccmalloc( unsigned int numberOfBytes ); +//! Frees ALL allocated memory space +void susan_wccfreeall( void ); +void *susan_wccmemcpy( void* dstpp, const void* srcpp, unsigned int len ); +void susan_wccmemset( void *p, int value, unsigned int num ); + +#endif diff --git a/all_pairs/tacleNames.txt b/all_pairs/tacleNames.txt new file mode 100644 index 0000000..8f4845a --- /dev/null +++ b/all_pairs/tacleNames.txt @@ -0,0 +1,19 @@ +petrinet +ndes +statemate +adpcm_dec +cjpeg_wrbmp +adpcm_enc +cjpeg_transupp +dijkstra +epic +fmref +gsm_dec +h264_dec +huff_enc +rijndael_enc +rijndael_dec +gsm_enc +susan +ammunition +mpeg2 diff --git a/baseline/Makefile b/baseline/Makefile new file mode 100644 index 0000000..53f53f4 --- /dev/null +++ b/baseline/Makefile @@ -0,0 +1,55 @@ +CC = gcc +CFLAGS = -pthread -O2 +LDFLAGS = -lrt +all: bin/cjpeg_wrbmp bin/huff_enc bin/gsm_enc bin/dijkstra bin/h264_dec bin/susan bin/adpcm_enc bin/rijndael_dec bin/huff_dec bin/rijndael_enc bin/gsm_dec bin/anagram bin/epic bin/ammunition bin/g723_enc bin/ndes bin/petrinet bin/statemate bin/cjpeg_transupp bin/mpeg2 bin/fmref bin/audiobeam bin/adpcm_dec + +.PHONY: clean +clean: + rm bin/cjpeg_wrbmp bin/huff_enc bin/gsm_enc bin/dijkstra bin/h264_dec bin/susan bin/adpcm_enc bin/rijndael_dec bin/huff_dec bin/rijndael_enc bin/gsm_dec bin/anagram bin/epic bin/ammunition bin/g723_enc bin/ndes bin/petrinet bin/statemate bin/cjpeg_transupp bin/mpeg2 bin/fmref bin/audiobeam bin/adpcm_dec + +bin/cjpeg_wrbmp: ./source/extra.h ./source/cjpeg_wrbmp/cjpeg_wrbmp.c ./source/cjpeg_wrbmp/input.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/huff_enc: ./source/extra.h ./source/huff_enc/huff_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/gsm_enc: ./source/extra.h ./source/gsm_enc/gsm_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/dijkstra: ./source/extra.h ./source/dijkstra/dijkstra.c ./source/dijkstra/input.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/h264_dec: ./source/extra.h ./source/h264_dec/h264_dec.c ./source/h264_dec/h264_decinput.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/susan: ./source/extra.h ./source/susan/input.c ./source/susan/susan.c ./source/susan/wccfile.c ./source/susan/wcclibm.c ./source/susan/wccmalloc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/adpcm_enc: ./source/extra.h ./source/adpcm_enc/adpcm_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/rijndael_dec: ./source/extra.h ./source/rijndael_dec/aes.c ./source/rijndael_dec/input_small_enc.c ./source/rijndael_dec/rijndael_dec.c ./source/rijndael_dec/rijndael_dec_libc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/huff_dec: ./source/extra.h ./source/huff_dec/huff_dec.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/rijndael_enc: ./source/extra.h ./source/rijndael_enc/aes.c ./source/rijndael_enc/input_small.c ./source/rijndael_enc/rijndael_enc.c ./source/rijndael_enc/rijndael_enc_libc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/gsm_dec: ./source/extra.h ./source/gsm_dec/gsm_dec.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/anagram: ./source/extra.h ./source/anagram/anagram.c ./source/anagram/anagram_input.c ./source/anagram/anagram_stdlib.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/epic: ./source/extra.h ./source/epic/epic.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/ammunition: ./source/extra.h ./source/ammunition/ammunition.c ./source/ammunition/ammunition_libc.c ./source/ammunition/arithm.c ./source/ammunition/bits.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/g723_enc: ./source/extra.h ./source/g723_enc/g723_enc.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/ndes: ./source/extra.h ./source/ndes/ndes.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/petrinet: ./source/extra.h ./source/petrinet/petrinet.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/statemate: ./source/extra.h ./source/statemate/statemate.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/cjpeg_transupp: ./source/extra.h ./source/cjpeg_transupp/cjpeg_transupp.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/mpeg2: ./source/extra.h ./source/mpeg2/mpeg2.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/fmref: ./source/extra.h ./source/fmref/fmref.c ./source/fmref/wcclibm.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/audiobeam: ./source/extra.h ./source/audiobeam/audiobeam.c ./source/audiobeam/audiobeaminput.c ./source/audiobeam/audiobeamlibmalloc.c ./source/audiobeam/audiobeamlibm.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) +bin/adpcm_dec: ./source/extra.h ./source/adpcm_dec/adpcm_dec.c + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) diff --git a/baseline/run_baseline.sh b/baseline/run_baseline.sh new file mode 100755 index 0000000..7fdc2aa --- /dev/null +++ b/baseline/run_baseline.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +core=$1 +maxJobs=$2 +runID=$3 +tacleNames=tacleNames.txt + +if [ $# -lt 3 ]; then + echo "Usage $0 [TACLe names file]" + exit +fi + +if [ $# -gt 3 ]; then + echo "Using alternate list of TACLe benchmarks from $4" + tacleNames=$4 +fi + +echo "Making sure that binaries are up to date..." +while read i; do + make bin/$i +done < $tacleNames +echo "Done. Disabling real-time throttling..." + +# Turn off rt throttling +echo -1 > /proc/sys/kernel/sched_rt_runtime_us +echo "Done. Redirecting all interrupts to core 0..." + +# Redirect all interrupts to core 0 +i=0 +for IRQ in /proc/irq/* +do + # Skip default_smp_affinity + if [ -d $IRQ ]; then + irqList[$i]=$(cat $IRQ/smp_affinity_list) + echo 0 > $IRQ/smp_affinity_list + fi + i=$(( $i + 1 )) +done +echo "Done. Beginning benchmarks..." + +# Read the names of each benchmark +j=0 +while read i; do + tacleProg[$j]=$i + j=$(( $j + 1 )) +done < $tacleNames + + +num_tests=$(wc -l < $tacleNames) +for (( i = 0; i < $num_tests ; i++ )) +do + chrt -r 97 taskset -c $core ./bin/${tacleProg[$i]} ${tacleProg[$i]} $maxJobs $core none none $runID 1 none + echo COMPLETE: ${tacleProg[$i]} +done + +# Put smp_affinty back the way it was +i=0 +for IRQ in /proc/irq/* +do + if [ -d $IRQ ]; then + echo ${irqList[$i]} > $IRQ/smp_affinity_list + fi + i=$(( $i + 1 )) +done + diff --git a/baseline/source/adpcm_dec/ChangeLog.txt b/baseline/source/adpcm_dec/ChangeLog.txt new file mode 100644 index 0000000..b9c4f96 --- /dev/null +++ b/baseline/source/adpcm_dec/ChangeLog.txt @@ -0,0 +1,32 @@ +File: minver.c +Original provenience: SNU-RT Benchmark Suite for Worst Case Timing Analysis + +2016-02-26: + - Added TACLeBench header to line 1 + - Rename global variable a to minver_a + - Rename global variable b to minver_b + - Rename global variable c to minver_c + - Rename global variable aa to minver_aa + - Rename global variable a_i to minver_a_i + - Rename global variable e to minver_e + - Rename global variable det to minver_det + - Renamed function minver to minver_minver + - Renamed function mmul to minver_mmul + - Renamed function fabs to minver_fabs + - Renamed function main to minver_main + - Created new function main, calling minver_init, minver_main and + returning minver_return + - Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions + - Applied code formatting with astyle as in the example + +2016-03-09: + - Removed static keyword for global variables + - Renamed global variables, prepended adpcm_dec + + 2016-05-23: + - Check sum added and checked against the expected value + + 2016-05-25: + - Corrected expected value \ No newline at end of file diff --git a/baseline/source/adpcm_dec/adpcm_dec.c b/baseline/source/adpcm_dec/adpcm_dec.c new file mode 100644 index 0000000..6811e69 --- /dev/null +++ b/baseline/source/adpcm_dec/adpcm_dec.c @@ -0,0 +1,719 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: adpcm_dec + + Author: Sung-Soo Lim + + Function: + CCITT G.722 ADPCM (Adaptive Differential Pulse Code Modulation) + algorithm. + 16khz sample rate data is stored in the array test_data[SIZE]. + Results are stored in the array compressed[SIZE] and result[SIZE]. + Execution time is determined by the constant SIZE (default value + is 2000). + + Source: SNU-RT Benchmark Suite + + Changes: adpcm benchmark was split into decode and encode benchmark + + License: may be used, modified, and re-distributed freely, but + the SNU-RT Benchmark Suite must be acknowledged + +*/ + +/* + This program is derived from the SNU-RT Benchmark Suite for Worst + Case Timing Analysis by Sung-Soo Lim + + Original source: C Algorithms for Real-Time DSP by P. M. Embree +*/ + +/* + Forward declaration of functions +*/ + +#include "../extra.h" + +void adpcm_dec_decode( int ); +int adpcm_dec_filtez( int *bpl, int *dlt ); +void adpcm_dec_upzero( int dlt, int *dlti, int *bli ); +int adpcm_dec_filtep( int rlt1, int al1, int rlt2, int al2 ); + +int adpcm_dec_logscl( int il, int nbl ); +int adpcm_dec_scalel( int nbl, int shift_constant ); +int adpcm_dec_uppol2( int al1, int al2, int plt, int plt1, int plt2 ); +int adpcm_dec_uppol1( int al1, int apl2, int plt, int plt1 ); + +int adpcm_dec_logsch( int ih, int nbh ); +void adpcm_dec_reset(); +int adpcm_dec_fabs( int n ); +int adpcm_dec_cos( int n ); +int adpcm_dec_sin( int n ); + +void adpcm_dec_init(); +int adpcm_dec_return(); +void adpcm_dec_main(); +//int main( void ); + + +/* + Declaration of macros +*/ +/* common sampling rate for sound cards on IBM/PC */ +#define SAMPLE_RATE 11025 +#define PI 3141 +#define SIZE 3 +#define IN_END 4 + +/* + Declaration of global variables +*/ + +int adpcm_dec_test_data[SIZE * 2], adpcm_dec_result[SIZE * 2]; + +/* Input data for the decoder usually generated by the encoder. */ +int adpcm_dec_compressed[SIZE] = { 0, 253, 32 }; + +/* G722 C code */ + +/* QMF filter coefficients: + scaled by a factor of 4 compared to G722 CCITT recommendation */ +int adpcm_dec_h[24] = { + 12, -44, -44, 212, 48, -624, 128, 1448, + -840, -3220, 3804, 15504, 15504, 3804, -3220, -840, + 1448, 128, -624, 48, 212, -44, -44, 12 +}; + +//int xl,xh; + +/* variables for receive quadrature mirror filter here */ +int adpcm_dec_accumc[11], adpcm_dec_accumd[11]; + +/* outputs of decode() */ +int adpcm_dec_xout1, adpcm_dec_xout2; + +int adpcm_dec_xs, adpcm_dec_xd; + +/* variables for encoder (hi and lo) here */ + +int adpcm_dec_il, adpcm_dec_szl, adpcm_dec_spl, adpcm_dec_sl, adpcm_dec_el; + +int adpcm_dec_qq4_code4_table[16] = { + 0, -20456, -12896, -8968, -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, 4240, 2584, 1200, 0 +}; + + +int adpcm_dec_qq6_code6_table[64] = { + -136, -136, -136, -136, -24808, -21904, -19008, -16704, + -14984, -13512, -12280, -11192, -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, 432, 136, -432, -136 +}; + + +int adpcm_dec_wl_code_table[16] = { + -60, 3042, 1198, 538, 334, 172, 58, -30, + 3042, 1198, 538, 334, 172, 58, -30, -60 +}; + + +int adpcm_dec_ilb_table[32] = { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, + 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834, + 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, + 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008 +}; + +int adpcm_dec_nbl; /* delay line */ +int adpcm_dec_al1, adpcm_dec_al2; +int adpcm_dec_plt, adpcm_dec_plt1, adpcm_dec_plt2; +int adpcm_dec_rs; +int adpcm_dec_dlt; +int adpcm_dec_rlt, adpcm_dec_rlt1, adpcm_dec_rlt2; + + +int adpcm_dec_detl; + + +int adpcm_dec_deth; +int adpcm_dec_sh; /* this comes from adaptive predictor */ +int adpcm_dec_eh; + +int adpcm_dec_qq2_code2_table[4] = { + -7408, -1616, 7408, 1616 +}; + +int adpcm_dec_wh_code_table[4] = { + 798, -214, 798, -214 +}; + + +int adpcm_dec_dh, adpcm_dec_ih; +int adpcm_dec_nbh, adpcm_dec_szh; +int adpcm_dec_sph, adpcm_dec_ph, adpcm_dec_yh, adpcm_dec_rh; + +int adpcm_dec_delay_dhx[6]; + +int adpcm_dec_delay_bph[6]; + +int adpcm_dec_ah1, adpcm_dec_ah2; +int adpcm_dec_ph1, adpcm_dec_ph2; +int adpcm_dec_rh1, adpcm_dec_rh2; + +/* variables for decoder here */ +int adpcm_dec_ilr, adpcm_dec_yl, adpcm_dec_rl; +int adpcm_dec_dec_deth, adpcm_dec_dec_detl, adpcm_dec_dec_dlt; + +int adpcm_dec_dec_del_bpl[6]; + +int adpcm_dec_dec_del_dltx[6]; + +int adpcm_dec_dec_plt, adpcm_dec_dec_plt1, adpcm_dec_dec_plt2; +int adpcm_dec_dec_szl, adpcm_dec_dec_spl, adpcm_dec_dec_sl; +int adpcm_dec_dec_rlt1, adpcm_dec_dec_rlt2, adpcm_dec_dec_rlt; +int adpcm_dec_dec_al1, adpcm_dec_dec_al2; +int adpcm_dec_dl; +int adpcm_dec_dec_nbl, adpcm_dec_dec_yh, adpcm_dec_dec_dh, adpcm_dec_dec_nbh; + +/* variables used in filtez */ +int adpcm_dec_dec_del_bph[6]; + +int adpcm_dec_dec_del_dhx[6]; + +int adpcm_dec_dec_szh; +/* variables used in filtep */ +int adpcm_dec_dec_rh1, adpcm_dec_dec_rh2; +int adpcm_dec_dec_ah1, adpcm_dec_dec_ah2; +int adpcm_dec_dec_ph, adpcm_dec_dec_sph; + +int adpcm_dec_dec_sh, adpcm_dec_dec_rh; + +int adpcm_dec_dec_ph1, adpcm_dec_dec_ph2; + + +/* + Arithmetic math functions +*/ + + +/* MAX: 1 */ +int adpcm_dec_fabs( int n ) +{ + int f; + + + if ( n >= 0 ) + f = n; + else + f = -n; + + return f; +} + + +int adpcm_dec_sin( int rad ) +{ + int diff; + int app = 0; + int inc = 1; + + + /* MAX dependent on rad's value, say 50 */ + _Pragma( "loopbound min 0 max 0" ) + while ( rad > 2 * PI ) + rad -= 2 * PI; + + _Pragma( "loopbound min 0 max 1999" ) + while ( rad < -2 * PI ) + rad += 2 * PI; + + diff = rad; + app = diff; + diff = ( diff * ( -( rad * rad ) ) ) / ( ( 2 * inc ) * ( 2 * inc + 1 ) ); + app = app + diff; + inc++; + + /* REALLY: while(my_fabs(diff) >= 0.00001) { */ + /* MAX: 1000 */ + _Pragma( "loopbound min 849 max 2424" ) + while ( adpcm_dec_fabs( diff ) >= 1 ) { + diff = ( diff * ( -( rad * rad ) ) ) / ( ( 2 * inc ) * ( 2 * inc + 1 ) ); + app = app + diff; + inc++; + } + + return app; +} + + +int adpcm_dec_cos( int rad ) +{ + return ( adpcm_dec_sin( PI / 2 - rad ) ); +} + + +/* + Algorithm core functions +*/ + +/* decode function, result in xout1 and xout2 */ +void adpcm_dec_decode( int input ) +{ + int i; + long int xa1, xa2; /* qmf accumulators */ + int *h_ptr, *ac_ptr, *ac_ptr1, *ad_ptr, *ad_ptr1; + + + /* split transmitted word from input into ilr and ih */ + adpcm_dec_ilr = input & 0x3f; + adpcm_dec_ih = input >> 6; + + /* LOWER SUB_BAND DECODER */ + + /* filtez: compute predictor output for zero section */ + adpcm_dec_dec_szl = adpcm_dec_filtez( adpcm_dec_dec_del_bpl, + adpcm_dec_dec_del_dltx ); + + /* filtep: compute predictor output signal for pole section */ + adpcm_dec_dec_spl = adpcm_dec_filtep( adpcm_dec_dec_rlt1, adpcm_dec_dec_al1, + adpcm_dec_dec_rlt2, adpcm_dec_dec_al2 ); + + adpcm_dec_dec_sl = adpcm_dec_dec_spl + adpcm_dec_dec_szl; + + /* invqxl: compute quantized difference signal for adaptive predic */ + adpcm_dec_dec_dlt = ( ( long )adpcm_dec_dec_detl * + adpcm_dec_qq4_code4_table[adpcm_dec_ilr + >> 2] ) >> 15; + + /* invqxl: compute quantized difference signal for decoder output */ + adpcm_dec_dl = ( ( long )adpcm_dec_dec_detl * + adpcm_dec_qq6_code6_table[adpcm_dec_il] ) >> + 15; + + adpcm_dec_rl = adpcm_dec_dl + adpcm_dec_dec_sl; + + /* logscl: quantizer scale factor adaptation in the lower sub-band */ + adpcm_dec_dec_nbl = adpcm_dec_logscl( adpcm_dec_ilr, adpcm_dec_dec_nbl ); + + /* scalel: computes quantizer scale factor in the lower sub band */ + adpcm_dec_dec_detl = adpcm_dec_scalel( adpcm_dec_dec_nbl, 8 ); + + /* parrec - add pole predictor output to quantized diff. signal */ + /* for partially reconstructed signal */ + adpcm_dec_dec_plt = adpcm_dec_dec_dlt + adpcm_dec_dec_szl; + + /* upzero: update zero section predictor coefficients */ + adpcm_dec_upzero( adpcm_dec_dec_dlt, adpcm_dec_dec_del_dltx, + adpcm_dec_dec_del_bpl ); + + /* uppol2: update second predictor coefficient apl2 and delay it as al2 */ + adpcm_dec_dec_al2 = adpcm_dec_uppol2( adpcm_dec_dec_al1, adpcm_dec_dec_al2, + adpcm_dec_dec_plt, adpcm_dec_dec_plt1, + adpcm_dec_dec_plt2 ); + + /* uppol1: update first predictor coef. (pole setion) */ + adpcm_dec_dec_al1 = adpcm_dec_uppol1( adpcm_dec_dec_al1, adpcm_dec_dec_al2, + adpcm_dec_dec_plt, adpcm_dec_dec_plt1 ); + + /* recons : compute recontructed signal for adaptive predictor */ + adpcm_dec_dec_rlt = adpcm_dec_dec_sl + adpcm_dec_dec_dlt; + + /* done with lower sub band decoder, implement delays for next time */ + adpcm_dec_dec_rlt2 = adpcm_dec_dec_rlt1; + adpcm_dec_dec_rlt1 = adpcm_dec_dec_rlt; + adpcm_dec_dec_plt2 = adpcm_dec_dec_plt1; + adpcm_dec_dec_plt1 = adpcm_dec_dec_plt; + + /* HIGH SUB-BAND DECODER */ + + /* filtez: compute predictor output for zero section */ + adpcm_dec_dec_szh = adpcm_dec_filtez( adpcm_dec_dec_del_bph, + adpcm_dec_dec_del_dhx ); + + /* filtep: compute predictor output signal for pole section */ + adpcm_dec_dec_sph = adpcm_dec_filtep( adpcm_dec_dec_rh1, adpcm_dec_dec_ah1, + adpcm_dec_dec_rh2, adpcm_dec_dec_ah2 ); + + /* predic:compute the predictor output value in the higher sub_band decoder */ + adpcm_dec_dec_sh = adpcm_dec_dec_sph + adpcm_dec_dec_szh; + + /* invqah: in-place compute the quantized difference signal */ + adpcm_dec_dec_dh = ( ( long )adpcm_dec_dec_deth * + adpcm_dec_qq2_code2_table[adpcm_dec_ih] ) >> 15L ; + + /* logsch: update logarithmic quantizer scale factor in hi sub band */ + adpcm_dec_dec_nbh = adpcm_dec_logsch( adpcm_dec_ih, adpcm_dec_dec_nbh ); + + /* scalel: compute the quantizer scale factor in the higher sub band */ + adpcm_dec_dec_deth = adpcm_dec_scalel( adpcm_dec_dec_nbh, 10 ); + + /* parrec: compute partially recontructed signal */ + adpcm_dec_dec_ph = adpcm_dec_dec_dh + adpcm_dec_dec_szh; + + /* upzero: update zero section predictor coefficients */ + adpcm_dec_upzero( adpcm_dec_dec_dh, adpcm_dec_dec_del_dhx, + adpcm_dec_dec_del_bph ); + + /* uppol2: update second predictor coefficient aph2 and delay it as ah2 */ + adpcm_dec_dec_ah2 = adpcm_dec_uppol2( adpcm_dec_dec_ah1, adpcm_dec_dec_ah2, + adpcm_dec_dec_ph, adpcm_dec_dec_ph1, adpcm_dec_dec_ph2 ); + + /* uppol1: update first predictor coef. (pole setion) */ + adpcm_dec_dec_ah1 = adpcm_dec_uppol1( adpcm_dec_dec_ah1, adpcm_dec_dec_ah2, + adpcm_dec_dec_ph, adpcm_dec_dec_ph1 ); + + /* recons : compute recontructed signal for adaptive predictor */ + adpcm_dec_rh = adpcm_dec_dec_sh + adpcm_dec_dec_dh; + + /* done with high band decode, implementing delays for next time here */ + adpcm_dec_dec_rh2 = adpcm_dec_dec_rh1; + adpcm_dec_dec_rh1 = adpcm_dec_rh; + adpcm_dec_dec_ph2 = adpcm_dec_dec_ph1; + adpcm_dec_dec_ph1 = adpcm_dec_dec_ph; + + /* end of higher sub_band decoder */ + + /* end with receive quadrature mirror filters */ + adpcm_dec_xd = adpcm_dec_rl - adpcm_dec_rh; + adpcm_dec_xs = adpcm_dec_rl + adpcm_dec_rh; + + /* receive quadrature mirror filters implemented here */ + h_ptr = adpcm_dec_h; + ac_ptr = adpcm_dec_accumc; + ad_ptr = adpcm_dec_accumd; + xa1 = ( long ) adpcm_dec_xd * ( *h_ptr++ ); + xa2 = ( long ) adpcm_dec_xs * ( *h_ptr++ ); + + /* main multiply accumulate loop for samples and coefficients */ + _Pragma( "loopbound min 10 max 10" ) + for ( i = 0; i < 10; i++ ) { + xa1 += ( long )( *ac_ptr++ ) * ( *h_ptr++ ); + xa2 += ( long )( *ad_ptr++ ) * ( *h_ptr++ ); + } + + /* final mult/accumulate */ + xa1 += ( long )( *ac_ptr ) * ( *h_ptr++ ); + xa2 += ( long )( *ad_ptr ) * ( *h_ptr++ ); + + /* scale by 2^14 */ + adpcm_dec_xout1 = xa1 >> 14; + adpcm_dec_xout2 = xa2 >> 14; + + /* update delay lines */ + ac_ptr1 = ac_ptr - 1; + ad_ptr1 = ad_ptr - 1; + + _Pragma( "loopbound min 10 max 10" ) + for ( i = 0; i < 10; i++ ) { + *ac_ptr-- = *ac_ptr1--; + *ad_ptr-- = *ad_ptr1--; + } + + *ac_ptr = adpcm_dec_xd; + *ad_ptr = adpcm_dec_xs; + + return; +} + + +/* filtez - compute predictor output signal (zero section) */ +/* input: bpl1-6 and dlt1-6, output: szl */ +int adpcm_dec_filtez( int *bpl, int *dlt ) +{ + int i; + long int zl; + + + zl = ( long )( *bpl++ ) * ( *dlt++ ); + + /* MAX: 5 */ + _Pragma( "loopbound min 5 max 5" ) + for ( i = 1; i < 6; i++ ) + zl += ( long )( *bpl++ ) * ( *dlt++ ); + + return ( ( int )( zl >> 14 ) ); /* x2 here */ +} + + +/* filtep - compute predictor output signal (pole section) */ +/* input rlt1-2 and al1-2, output spl */ +int adpcm_dec_filtep( int rlt1, int al1, int rlt2, int al2 ) +{ + long int pl, pl2; + + + pl = 2 * rlt1; + pl = ( long ) al1 * pl; + pl2 = 2 * rlt2; + pl += ( long ) al2 * pl2; + + return ( ( int )( pl >> 15 ) ); +} + + +/* logscl - update log quantizer scale factor in lower sub-band */ +/* note that nbl is passed and returned */ +int adpcm_dec_logscl( int il, int nbl ) +{ + long int wd; + + + wd = ( ( long )nbl * 127L ) >> 7L; /* leak factor 127/128 */ + nbl = ( int )wd + adpcm_dec_wl_code_table[il >> 2]; + + if ( nbl < 0 ) + nbl = 0; + if ( nbl > 18432 ) + nbl = 18432; + + return ( nbl ); +} + + +/* scalel: compute quantizer scale factor in lower or upper sub-band*/ +int adpcm_dec_scalel( int nbl, int shift_constant ) +{ + int wd1, wd2, wd3; + + + wd1 = ( nbl >> 6 ) & 31; + wd2 = nbl >> 11; + wd3 = adpcm_dec_ilb_table[wd1] >> ( shift_constant + 1 - wd2 ); + + return ( wd3 << 3 ); +} + + +/* upzero - inputs: dlt, dlti[0-5], bli[0-5], outputs: updated bli[0-5] */ +/* also implements delay of bli and update of dlti from dlt */ +void adpcm_dec_upzero( int dlt, int *dlti, int *bli ) +{ + int i, wd2, wd3; + + + /*if dlt is zero, then no sum into bli */ + if ( dlt == 0 ) { + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + bli[i] = ( int )( ( 255L * bli[i] ) >> 8L ); /* leak factor of 255/256 */ + } + + } else { + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + if ( ( long )dlt * dlti[i] >= 0 ) + wd2 = 128; + else + wd2 = -128; + + wd3 = ( int )( ( 255L * bli[i] ) >> 8L ); /* leak factor of 255/256 */ + bli[i] = wd2 + wd3; + } + + } + + /* implement delay line for dlt */ + dlti[5] = dlti[4]; + dlti[4] = dlti[3]; + dlti[3] = dlti[2]; + dlti[1] = dlti[0]; + dlti[0] = dlt; + + return; +} + + +/* uppol2 - update second predictor coefficient (pole section) */ +/* inputs: al1, al2, plt, plt1, plt2. outputs: apl2 */ +int adpcm_dec_uppol2( int al1, int al2, int plt, int plt1, int plt2 ) +{ + long int wd2, wd4; + int apl2; + + + wd2 = 4L * ( long )al1; + if ( ( long )plt * plt1 >= 0L ) + wd2 = -wd2; /* check same sign */ + wd2 = wd2 >> 7; /* gain of 1/128 */ + + if ( ( long )plt * plt2 >= 0L ) { + wd4 = wd2 + 128; /* same sign case */ + } else + wd4 = wd2 - 128; + apl2 = wd4 + ( 127L * ( long )al2 >> 7L ); /* leak factor of 127/128 */ + + /* apl2 is limited to +-.75 */ + if ( apl2 > 12288 ) + apl2 = 12288; + if ( apl2 < -12288 ) + apl2 = -12288; + + return ( apl2 ); +} + + +/* uppol1 - update first predictor coefficient (pole section) */ +/* inputs: al1, apl2, plt, plt1. outputs: apl1 */ +int adpcm_dec_uppol1( int al1, int apl2, int plt, int plt1 ) +{ + long int wd2; + int wd3, apl1; + + + wd2 = ( ( long )al1 * 255L ) >> 8L; /* leak factor of 255/256 */ + if ( ( long )plt * plt1 >= 0L ) { + apl1 = ( int )wd2 + 192; /* same sign case */ + } else + apl1 = ( int )wd2 - 192; + + /* note: wd3= .9375-.75 is always positive */ + wd3 = 15360 - apl2; /* limit value */ + if ( apl1 > wd3 ) + apl1 = wd3; + if ( apl1 < -wd3 ) + apl1 = -wd3; + + return ( apl1 ); +} + + +/* logsch - update log quantizer scale factor in higher sub-band */ +/* note that nbh is passed and returned */ +int adpcm_dec_logsch( int ih, int nbh ) +{ + int wd; + + + wd = ( ( long )nbh * 127L ) >> 7L; /* leak factor 127/128 */ + nbh = wd + adpcm_dec_wh_code_table[ih]; + + if ( nbh < 0 ) + nbh = 0; + if ( nbh > 22528 ) + nbh = 22528; + + return ( nbh ); +} + +/* + Initialization- and return-value-related functions +*/ + +/* clear all storage locations */ + +void adpcm_dec_reset() +{ + int i; + + + adpcm_dec_detl = adpcm_dec_dec_detl = 32; /* reset to min scale factor */ + adpcm_dec_deth = adpcm_dec_dec_deth = 8; + adpcm_dec_nbl = adpcm_dec_al1 = adpcm_dec_al2 = adpcm_dec_plt1 = adpcm_dec_plt2 + = adpcm_dec_rlt1 = adpcm_dec_rlt2 = 0; + adpcm_dec_nbh = adpcm_dec_ah1 = adpcm_dec_ah2 = adpcm_dec_ph1 = adpcm_dec_ph2 = + adpcm_dec_rh1 = adpcm_dec_rh2 = 0; + adpcm_dec_dec_nbl = adpcm_dec_dec_al1 = adpcm_dec_dec_al2 = adpcm_dec_dec_plt1 = + adpcm_dec_dec_plt2 = adpcm_dec_dec_rlt1 = adpcm_dec_dec_rlt2 = 0; + adpcm_dec_dec_nbh = adpcm_dec_dec_ah1 = adpcm_dec_dec_ah2 = adpcm_dec_dec_ph1 = + adpcm_dec_dec_ph2 = adpcm_dec_dec_rh1 = adpcm_dec_dec_rh2 = 0; + + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + ////delay_dltx[i] = 0; + adpcm_dec_delay_dhx[i] = 0; + adpcm_dec_dec_del_dltx[i] = 0; + adpcm_dec_dec_del_dhx[i] = 0; + } + + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) { + //delay_bpl[i] = 0; + adpcm_dec_delay_bph[i] = 0; + adpcm_dec_dec_del_bpl[i] = 0; + adpcm_dec_dec_del_bph[i] = 0; + } + + _Pragma( "loopbound min 11 max 11" ) + for ( i = 0; i < 11; i++ ) { + adpcm_dec_accumc[i] = 0; + adpcm_dec_accumd[i] = 0; + } + + return; +} + +void adpcm_dec_init() +{ + int i, j, f; + volatile int x = 0; + /* read in amplitude and frequency for test data */ + j = 10; + f = 2000; + + /* reset, initialize required memory */ + adpcm_dec_reset(); + + /* 16 KHz sample rate */ + /* XXmain_0, MAX: 2 */ + /* Since the number of times we loop in adpcm_dec_sin depends on the + argument we add the fact: xxmain_0:[]: */ + _Pragma( "loopbound min 3 max 3" ) + for ( i = 0 ; i < SIZE ; i++ ) { + adpcm_dec_test_data[i] = ( int ) j * adpcm_dec_cos( f * PI * i ); + + /* avoid constant-propagation optimizations */ + adpcm_dec_test_data[i] += x; + } +} + +int adpcm_dec_return() +{ + int i; + int check_sum = 0; + + for (i = 0; i < IN_END; i += 2) + { + check_sum += ( adpcm_dec_result[i] + adpcm_dec_result[i + 1] ); + } + + return check_sum != -2; +} + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) adpcm_dec_main( void ) +{ + int i; + + _Pragma( "loopbound min 2 max 2" ) + for ( i = 0 ; i < IN_END ; i += 2 ) { + adpcm_dec_decode( adpcm_dec_compressed[i / 2] ); + adpcm_dec_result[i] = adpcm_dec_xout1; + adpcm_dec_result[i + 1] = adpcm_dec_xout2; + } + +} + + +int main(int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsComplete + + Original name: adpcm_encoder + + Changes: no major functional changes + + License: may be used, modified, and re-distributed freely, but the + SNU-RT Benchmark Suite must be acknowledged + +*/ + + +/* common sampling rate for sound cards on IBM/PC */ + +#include "../extra.h" +#define SAMPLE_RATE 11025 + +#define PI 3141 +#define SIZE 3 +#define IN_END 4 + + +/* + Forward declaration of functions +*/ + +int adpcm_enc_encode( int, int ); +int adpcm_enc_filtez( int *bpl, int *dlt ); +void adpcm_enc_upzero( int dlt, int *dlti, int *bli ); +int adpcm_enc_filtep( int rlt1, int al1, int rlt2, int al2 ); +int adpcm_enc_quantl( int el, int detl ); +int adpcm_enc_logscl( int il, int nbl ); +int adpcm_enc_scalel( int nbl, int shift_constant ); +int adpcm_enc_uppol2( int al1, int al2, int plt, int plt1, int plt2 ); +int adpcm_enc_uppol1( int al1, int apl2, int plt, int plt1 ); +int adpcm_enc_logsch( int ih, int nbh ); +void adpcm_enc_reset(); +int adpcm_enc_fabs( int n ); +int adpcm_enc_cos( int n ); +int adpcm_enc_sin( int n ); +int adpcm_enc_abs( int n ); +void adpcm_enc_init(void); +void adpcm_enc_main(void); +int adpcm_enc_return(void); +//int main(void); + +/* + Forward declaration of global variables +*/ + +int adpcm_enc_test_data[SIZE * 2], adpcm_enc_compressed[SIZE]; + + +/* G722 C code */ + +/* variables for transimit quadrature mirror filter here */ +int adpcm_enc_tqmf[24]; + +/* QMF filter coefficients: +scaled by a factor of 4 compared to G722 CCITT recommendation */ +int adpcm_enc_h[24] = { + 12, -44, -44, 212, 48, -624, 128, 1448, + -840, -3220, 3804, 15504, 15504, 3804, -3220, -840, + 1448, 128, -624, 48, 212, -44, -44, 12 +}; + +int adpcm_enc_xl, adpcm_enc_xh; + +/* variables for encoder (hi and lo) here */ + +int adpcm_enc_il, adpcm_enc_szl, adpcm_enc_spl, adpcm_enc_sl, adpcm_enc_el; + +int adpcm_enc_qq4_code4_table[16] = { + 0, -20456, -12896, -8968, -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, 4240, 2584, 1200, 0 +}; + +int adpcm_enc_qq5_code5_table[32] = { + -280, -280, -23352, -17560, -14120, -11664, -9752, -8184, + -6864, -5712, -4696, -3784, -2960, -2208, -1520, -880, + 23352, 17560, 14120, 11664, 9752, 8184, 6864, 5712, + 4696, 3784, 2960, 2208, 1520, 880, 280, -280 +}; + +int adpcm_enc_qq6_code6_table[64] = { + -136, -136, -136, -136, -24808, -21904, -19008, -16704, +-14984, -13512, -12280, -11192, -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, 432, 136, -432, -136 +}; + +int adpcm_enc_delay_bpl[6]; + +int adpcm_enc_delay_dltx[6]; + +int adpcm_enc_wl_code_table[16] = { + -60, 3042, 1198, 538, 334, 172, 58, -30, + 3042, 1198, 538, 334, 172, 58, -30, -60 +}; + +int adpcm_enc_ilb_table[32] = { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, + 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834, + 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, + 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008 +}; + +int adpcm_enc_nbl; /* delay line */ +int adpcm_enc_al1, adpcm_enc_al2; +int adpcm_enc_plt, adpcm_enc_plt1, adpcm_enc_plt2; +int adpcm_enc_dlt; +int adpcm_enc_rlt, adpcm_enc_rlt1, adpcm_enc_rlt2; + +/* decision levels - pre-multiplied by 8, 0 to indicate end */ +int adpcm_enc_decis_levl[30] = { + 280, 576, 880, 1200, 1520, 1864, 2208, 2584, + 2960, 3376, 3784, 4240, 4696, 5200, 5712, 6288, + 6864, 7520, 8184, 8968, 9752, 10712, 11664, 12896, + 14120, 15840, 17560, 20456, 23352, 32767 +}; + +int adpcm_enc_detl; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +int adpcm_enc_quant26bt_pos[31] = { + 61, 60, 59, 58, 57, 56, 55, 54, + 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 38, + 37, 36, 35, 34, 33, 32, 32 +}; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +int adpcm_enc_quant26bt_neg[31] = { + 63, 62, 31, 30, 29, 28, 27, 26, + 25, 24, 23, 22, 21, 20, 19, 18, + 17, 16, 15, 14, 13, 12, 11, 10, + 9, 8, 7, 6, 5, 4, 4 +}; + + +int adpcm_enc_deth; +int adpcm_enc_sh; /* this comes from adaptive predictor */ +int adpcm_enc_eh; + +int adpcm_enc_qq2_code2_table[4] = { + -7408, -1616, 7408, 1616 +}; + +int adpcm_enc_wh_code_table[4] = { + 798, -214, 798, -214 +}; + + +int adpcm_enc_dh, adpcm_enc_ih; +int adpcm_enc_nbh, adpcm_enc_szh; +int adpcm_enc_sph, adpcm_enc_ph, adpcm_enc_yh; + +int adpcm_enc_delay_dhx[6]; +int adpcm_enc_delay_bph[6]; + +int adpcm_enc_ah1, adpcm_enc_ah2; +int adpcm_enc_ph1, adpcm_enc_ph2; +int adpcm_enc_rh1, adpcm_enc_rh2; + + +/* G722 encode function two ints in, one 8 bit output */ + +/* put input samples in xin1 = first value, xin2 = second value */ +/* returns il and ih stored together */ + + +/* MAX: 1 */ +int adpcm_enc_abs( int n ) +{ + int m; + + + if ( n >= 0 ) + m = n; + else + m = -n; + + return m; +} + + +/* MAX: 1 */ +int adpcm_enc_fabs( int n ) +{ + int f; + + + if ( n >= 0 ) + f = n; + else + f = -n; + + return f; +} + + +int adpcm_enc_sin( int rad ) +{ + int diff; + int app = 0; + int inc = 1; + + + /* MAX dependent on rad's value, say 50 */ + _Pragma("loopbound min 0 max 0") + while ( rad > 2 * PI ) { + rad -= 2 * PI; + } + + /* MAX dependent on rad's value, say 50 */ + _Pragma("loopbound min 0 max 1999") + while ( rad < -2 * PI ) { + rad += 2 * PI; + } + + diff = rad; + app = diff; + diff = (diff * (-(rad*rad))) / ((2 * inc) * (2 * inc + 1)); + app = app + diff; + inc++; + + /* REALLY: while(my_fabs(diff) >= 0.00001) { */ + /* MAX: 1000 */ + _Pragma("loopbound min 849 max 2424") + while ( adpcm_enc_fabs( diff ) >= 1 ) { + diff = (diff * (-(rad*rad))) / ((2 * inc) * (2 * inc + 1)); + app = app + diff; + inc++; + } + + return app; +} + + +int adpcm_enc_cos( int rad ) +{ + return( adpcm_enc_sin( PI / 2 - rad ) ); +} + + +/* MAX: 1 */ +int adpcm_enc_encode( int xin1, int xin2 ) +{ + int i; + int *h_ptr, *tqmf_ptr, *tqmf_ptr1; + long int xa, xb; + int decis; + + + /* transmit quadrature mirror filters implemented here */ + h_ptr = adpcm_enc_h; + tqmf_ptr = adpcm_enc_tqmf; + xa = (long)(*tqmf_ptr++) * (*h_ptr++); + xb = (long)(*tqmf_ptr++) * (*h_ptr++); + + /* main multiply accumulate loop for samples and coefficients */ + /* MAX: 10 */ + _Pragma("loopbound min 10 max 10") + for ( i = 0; i < 10; i++ ) { + xa += (long)(*tqmf_ptr++) * (*h_ptr++); + xb += (long)(*tqmf_ptr++) * (*h_ptr++); + } + + /* final mult/accumulate */ + xa += (long)(*tqmf_ptr++) * (*h_ptr++); + xb += (long)(*tqmf_ptr) * (*h_ptr++); + + /* update delay line tqmf */ + tqmf_ptr1 = tqmf_ptr - 2; + /* MAX: 22 */ + _Pragma("loopbound min 22 max 22") + for ( i = 0; i < 22; i++ ) { + *tqmf_ptr-- = *tqmf_ptr1--; + } + + *tqmf_ptr-- = xin1; + *tqmf_ptr = xin2; + + /* scale outputs */ + adpcm_enc_xl = (xa + xb) >> 15; + adpcm_enc_xh = (xa - xb) >> 15; + + /* end of quadrature mirror filter code */ + + /* starting with lower sub band encoder */ + + /* filtez - compute predictor output section - zero section */ + adpcm_enc_szl = adpcm_enc_filtez( adpcm_enc_delay_bpl, adpcm_enc_delay_dltx ); + + /* filtep - compute predictor output signal (pole section) */ + adpcm_enc_spl = adpcm_enc_filtep( adpcm_enc_rlt1, adpcm_enc_al1, adpcm_enc_rlt2, adpcm_enc_al2 ); + + /* compute the predictor output value in the lower sub_band encoder */ + adpcm_enc_sl = adpcm_enc_szl + adpcm_enc_spl; + adpcm_enc_el = adpcm_enc_xl - adpcm_enc_sl; + + /* quantl: quantize the difference signal */ + adpcm_enc_il = adpcm_enc_quantl( adpcm_enc_el, adpcm_enc_detl ); + + /* invqxl: computes quantized difference signal */ + /* for invqbl, truncate by 2 lsbs, so mode = 3 */ + adpcm_enc_dlt = ( (long) adpcm_enc_detl * adpcm_enc_qq4_code4_table[adpcm_enc_il >> 2] ) >> 15; + + /* logscl: updates logarithmic quant. scale factor in low sub band */ + adpcm_enc_nbl = adpcm_enc_logscl( adpcm_enc_il, adpcm_enc_nbl ); + + /* scalel: compute the quantizer scale factor in the lower sub band */ + /* calling parameters nbl and 8 (constant such that scalel can be scaleh) */ + adpcm_enc_detl = adpcm_enc_scalel( adpcm_enc_nbl, 8 ); + + /* parrec - simple addition to compute recontructed signal for adaptive pred */ + adpcm_enc_plt = adpcm_enc_dlt + adpcm_enc_szl; + + /* upzero: update zero section predictor coefficients (sixth order)*/ + /* calling parameters: dlt, dlt1, dlt2, ..., dlt6 from dlt */ + /* bpli (linear_buffer in which all six values are delayed */ + /* return params: updated bpli, delayed dltx */ + adpcm_enc_upzero( adpcm_enc_dlt, adpcm_enc_delay_dltx, adpcm_enc_delay_bpl ); + + /* uppol2- update second predictor coefficient apl2 and delay it as al2 */ + /* calling parameters: al1, al2, plt, plt1, plt2 */ + adpcm_enc_al2 = adpcm_enc_uppol2( adpcm_enc_al1, adpcm_enc_al2, adpcm_enc_plt, adpcm_enc_plt1, adpcm_enc_plt2 ); + + /* uppol1 :update first predictor coefficient apl1 and delay it as al1 */ + /* calling parameters: al1, apl2, plt, plt1 */ + adpcm_enc_al1 = adpcm_enc_uppol1( adpcm_enc_al1, adpcm_enc_al2, adpcm_enc_plt, adpcm_enc_plt1); + + /* recons : compute recontructed signal for adaptive predictor */ + adpcm_enc_rlt = adpcm_enc_sl + adpcm_enc_dlt; + + /* done with lower sub_band encoder; now implement delays for next time*/ + adpcm_enc_rlt2 = adpcm_enc_rlt1; + adpcm_enc_rlt1 = adpcm_enc_rlt; + adpcm_enc_plt2 = adpcm_enc_plt1; + adpcm_enc_plt1 = adpcm_enc_plt; + + /* high band encode */ + + adpcm_enc_szh = adpcm_enc_filtez( adpcm_enc_delay_bph, adpcm_enc_delay_dhx ); + + adpcm_enc_sph = adpcm_enc_filtep( adpcm_enc_rh1, adpcm_enc_ah1, adpcm_enc_rh2, adpcm_enc_ah2 ); + + /* predic: sh = sph + szh */ + adpcm_enc_sh = adpcm_enc_sph + adpcm_enc_szh; + /* subtra: eh = xh - sh */ + adpcm_enc_eh = adpcm_enc_xh - adpcm_enc_sh; + + /* quanth - quantization of difference signal for higher sub-band */ + /* quanth: in-place for speed params: eh, deth (has init. value) */ + if ( adpcm_enc_eh >= 0 ) + adpcm_enc_ih = 3; /* 2,3 are pos codes */ + else + adpcm_enc_ih = 1; /* 0,1 are neg codes */ + + decis = ( 564L * (long)adpcm_enc_deth ) >> 12L; + if ( adpcm_enc_abs( adpcm_enc_eh ) > decis ) + adpcm_enc_ih--; /* mih = 2 case */ + + /* invqah: compute the quantized difference signal, higher sub-band*/ + adpcm_enc_dh = ( (long)adpcm_enc_deth * adpcm_enc_qq2_code2_table[adpcm_enc_ih] ) >> 15L ; + + /* logsch: update logarithmic quantizer scale factor in hi sub-band*/ + adpcm_enc_nbh = adpcm_enc_logsch( adpcm_enc_ih, adpcm_enc_nbh ); + + /* note : scalel and scaleh use same code, different parameters */ + adpcm_enc_deth = adpcm_enc_scalel( adpcm_enc_nbh, 10 ); + + /* parrec - add pole predictor output to quantized diff. signal */ + adpcm_enc_ph = adpcm_enc_dh + adpcm_enc_szh; + + /* upzero: update zero section predictor coefficients (sixth order) */ + /* calling parameters: dh, dhi, bphi */ + /* return params: updated bphi, delayed dhx */ + adpcm_enc_upzero( adpcm_enc_dh, adpcm_enc_delay_dhx, adpcm_enc_delay_bph ); + + /* uppol2: update second predictor coef aph2 and delay as ah2 */ + /* calling params: ah1, ah2, ph, ph1, ph2 */ + adpcm_enc_ah2 = adpcm_enc_uppol2( adpcm_enc_ah1, adpcm_enc_ah2, adpcm_enc_ph, adpcm_enc_ph1, adpcm_enc_ph2 ); + + /* uppol1: update first predictor coef. aph2 and delay it as ah1 */ + adpcm_enc_ah1 = adpcm_enc_uppol1( adpcm_enc_ah1, adpcm_enc_ah2, adpcm_enc_ph, adpcm_enc_ph1 ); + + /* recons for higher sub-band */ + adpcm_enc_yh = adpcm_enc_sh + adpcm_enc_dh; + + /* done with higher sub-band encoder, now Delay for next time */ + adpcm_enc_rh2 = adpcm_enc_rh1; + adpcm_enc_rh1 = adpcm_enc_yh; + adpcm_enc_ph2 = adpcm_enc_ph1; + adpcm_enc_ph1 = adpcm_enc_ph; + + /* multiplex ih and il to get signals together */ + return( adpcm_enc_il | (adpcm_enc_ih << 6) ); +} + + +/* filtez - compute predictor output signal (zero section) */ +/* input: bpl1-6 and dlt1-6, output: szl */ +int adpcm_enc_filtez( int *bpl, int *dlt ) +{ + int i; + long int zl; + + + zl = (long)(*bpl++) * (*dlt++); + + /* MAX: 5 */ + _Pragma("loopbound min 5 max 5") + for ( i = 1; i < 6; i++ ) { + zl += (long)(*bpl++) * (*dlt++); + } + + return( (int)(zl >> 14) ); /* x2 here */ +} + + +/* filtep - compute predictor output signal (pole section) */ +/* input rlt1-2 and al1-2, output spl */ +int adpcm_enc_filtep( int rlt1, int al1, int rlt2, int al2 ) +{ + long int pl, pl2; + + + pl = 2 * rlt1; + pl = (long) al1 * pl; + pl2 = 2 * rlt2; + pl += (long) al2 * pl2; + + return( (int)(pl >> 15) ); +} + + +/* quantl - quantize the difference signal in the lower sub-band */ +int adpcm_enc_quantl( int el, int detl ) +{ + int ril, mil; + long int wd, decis; + + + /* abs of difference signal */ + wd = adpcm_enc_abs( el ); + + /* determine mil based on decision levels and detl gain */ + /* MAX: 30 */ + _Pragma("loopbound min 1 max 30") + for ( mil = 0; mil < 30; mil++ ) { + decis = (adpcm_enc_decis_levl[mil] * (long)detl) >> 15L; + if ( wd <= decis ) + break; + } + + /* if mil=30 then wd is less than all decision levels */ + if ( el >= 0 ) + ril = adpcm_enc_quant26bt_pos[mil]; + else + ril = adpcm_enc_quant26bt_neg[mil]; + + return( ril ); +} + + +/* invqxl is either invqbl or invqal depending on parameters passed */ +/* returns dlt, code table is pre-multiplied by 8 */ + +/* int invqxl(int il,int detl,int *code_table,int mode) */ +/* { */ +/* long int dlt; */ +/* dlt = (long)detl*code_table[il >> (mode-1)]; */ +/* return((int)(dlt >> 15)); */ +/* } */ + +/* logscl - update log quantizer scale factor in lower sub-band */ +/* note that nbl is passed and returned */ +int adpcm_enc_logscl( int il, int nbl ) +{ + long int wd; + + + wd = ((long)nbl * 127L) >> 7L; /* leak factor 127/128 */ + nbl = (int)wd + adpcm_enc_wl_code_table[il >> 2]; + + if ( nbl < 0 ) + nbl = 0; + if ( nbl > 18432 ) + nbl = 18432; + + return( nbl ); +} + + +/* scalel: compute quantizer scale factor in lower or upper sub-band*/ +int adpcm_enc_scalel( int nbl, int shift_constant ) +{ + int wd1, wd2, wd3; + + + wd1 = (nbl >> 6) & 31; + wd2 = nbl >> 11; + wd3 = adpcm_enc_ilb_table[wd1] >> (shift_constant + 1 - wd2); + + return( wd3 << 3 ); +} + + +/* upzero - inputs: dlt, dlti[0-5], bli[0-5], outputs: updated bli[0-5] */ +/* also implements delay of bli and update of dlti from dlt */ +void adpcm_enc_upzero( int dlt, int *dlti, int *bli ) +{ + int i, wd2, wd3; + + + /*if dlt is zero, then no sum into bli */ + if ( dlt == 0 ) { + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++ ) { + bli[i] = (int)((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + } + + } else { + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++ ) { + if ( (long)dlt * dlti[i] >= 0 ) + wd2 = 128; + else + wd2 = -128; + + wd3 = (int)((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + bli[i] = wd2 + wd3; + } + + } + + /* implement delay line for dlt */ + dlti[5] = dlti[4]; + dlti[4] = dlti[3]; + dlti[3] = dlti[2]; + dlti[1] = dlti[0]; + dlti[0] = dlt; + + return; +} + + +/* uppol2 - update second predictor coefficient (pole section) */ +/* inputs: al1, al2, plt, plt1, plt2. outputs: apl2 */ +int adpcm_enc_uppol2( int al1, int al2, int plt, int plt1, int plt2 ) +{ + long int wd2, wd4; + int apl2; + + + wd2 = 4L * (long)al1; + if ( (long)plt * plt1 >= 0L ) + wd2 = -wd2; /* check same sign */ + wd2 = wd2 >> 7; /* gain of 1/128 */ + + if ( (long)plt * plt2 >= 0L ) { + wd4 = wd2 + 128; /* same sign case */ + } else { + wd4 = wd2 - 128; + } + apl2 = wd4 + (127L*(long)al2 >> 7L); /* leak factor of 127/128 */ + + /* apl2 is limited to +-.75 */ + if ( apl2 > 12288 ) + apl2 = 12288; + if ( apl2 < -12288 ) + apl2 = -12288; + + return( apl2 ); +} + + +/* uppol1 - update first predictor coefficient (pole section) */ +/* inputs: al1, apl2, plt, plt1. outputs: apl1 */ +int adpcm_enc_uppol1( int al1, int apl2, int plt, int plt1 ) +{ + long int wd2; + int wd3, apl1; + + + wd2 = ((long)al1 * 255L) >> 8L; /* leak factor of 255/256 */ + if ( (long)plt * plt1 >= 0L ) { + apl1 = (int)wd2 + 192; /* same sign case */ + } else { + apl1 = (int)wd2 - 192; + } + + /* note: wd3= .9375-.75 is always positive */ + wd3 = 15360 - apl2; /* limit value */ + if ( apl1 > wd3 ) + apl1 = wd3; + if ( apl1 < -wd3 ) + apl1 = -wd3; + + return( apl1 ); +} + + +/* INVQAH: inverse adaptive quantizer for the higher sub-band */ +/* returns dh, code table is pre-multiplied by 8 */ +/* int invqah(int ih,int deth) */ +/* { */ +/* long int rdh; */ +/* rdh = ((long)deth*qq2_code2_table[ih]) >> 15L ; */ +/* return((int)(rdh )); */ +/* } */ + + +/* logsch - update log quantizer scale factor in higher sub-band */ +/* note that nbh is passed and returned */ +int adpcm_enc_logsch( int ih, int nbh ) +{ + int wd; + + + wd = ((long)nbh * 127L) >> 7L; /* leak factor 127/128 */ + nbh = wd + adpcm_enc_wh_code_table[ih]; + + if ( nbh < 0 ) + nbh = 0; + if ( nbh > 22528 ) + nbh = 22528; + + return( nbh ); +} + + +/* + Initialization- and return-value-related functions +*/ + +/* clear all storage locations */ + +void adpcm_enc_reset(void) +{ + int i; + + adpcm_enc_detl = 32; /* reset to min scale factor */ + adpcm_enc_deth = 8; + adpcm_enc_nbl = adpcm_enc_al1 = adpcm_enc_al2 = adpcm_enc_plt1 = adpcm_enc_plt2 = adpcm_enc_rlt1 = adpcm_enc_rlt2 = 0; + adpcm_enc_nbh = adpcm_enc_ah1 = adpcm_enc_ah2 = adpcm_enc_ph1 = adpcm_enc_ph2 = adpcm_enc_rh1 = adpcm_enc_rh2 = 0; + + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++) { + adpcm_enc_delay_dltx[i] = 0; + adpcm_enc_delay_dhx[i] = 0; + } + + _Pragma("loopbound min 6 max 6") + for ( i = 0; i < 6; i++ ) { + adpcm_enc_delay_bpl[i] = 0; + adpcm_enc_delay_bph[i] = 0; + } + + _Pragma("loopbound min 23 max 23") + for ( i = 0; i < 23; i++ ) { + adpcm_enc_tqmf[i] = 0; + } + + return; +} + + +void adpcm_enc_init(void) +{ + int i, j, f; + volatile int x = 0; + + /* reset, initialize required memory */ + adpcm_enc_reset(); + + /* read in amplitude and frequency for test data */ + j = 10; + f = 2000; + + /* 16 KHz sample rate */ + /* XXmain_0, MAX: 2 */ + /* Since the number of times we loop in my_sin depends on the argument we + add the fact: xxmain_0:[]: */ + _Pragma("loopbound min 3 max 3") + for ( i = 0 ; i < SIZE ; i++) { + adpcm_enc_test_data[i] = (int) j * adpcm_enc_cos( f * PI * i ); + + /* avoid constant-propagation optimizations */ + adpcm_enc_test_data[i] += x; + } +} + + +int adpcm_enc_return(void) +{ + int i; + int check_sum = 0; + + for ( i = 0 ; i < IN_END ; i += 2 ) { + check_sum += adpcm_enc_compressed[i/2]; + } + + return check_sum != 385; +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) adpcm_enc_main(void) +{ + int i; + /* MAX: 2 */ + _Pragma("loopbound min 2 max 2") + for ( i = 0 ; i < IN_END ; i += 2 ) { + adpcm_enc_compressed[i/2] = adpcm_enc_encode( adpcm_enc_test_data[i], adpcm_enc_test_data[i+1] ); + } + +} + +int main(int argc, char **argv) +{ + SET_UP + for(jobsComplete=-1; jobsComplete unsigned char +- Fix compiler warnings "'&&' within '||'": + Place additional parentheses +- Remove usages and comments related to the macros + HAVE_MEMMOVE, NDEBUG, HAVE_MEMCMP +- Remove comment related to unused NO_TEMPLATE macro +2016-05-02: +- Change C++ style comments to ISO C90 compliant comments +- Avoid mixing declarations and code: move declaration of variable writePos in + functions ammunition_sprintf_d and ammunition_sprintf_u +- Change datatype in function ammunition_bits_test of iteration variables i and + j from int to unsigned int to avoid comparison between signed and unsigned + integer expressions +- Add forward declarations to ammunition.c +- Introduce variable ammunition_result +- Parantheses around comparison in functions ammunition_isdigit and + ammunition_isspace +- Remove usage of limits.h, move definitions of limits into separate file + ammunition_limits.h +- Remove unconditional assignments of variable result to zero after each test in + functions ammunition_bits_test and ammunition_arithm_test +- Remove unused functions unsigned_integer_maximum, integer_minimum, + integer_maximum, integer_remainder +- Remove unused declaration of function default_arithmetic_overflow_reaction +- Remove unused variables zero_constant_itself, zero_constant +- Remove unused declarations of functions set_unsigned_integer_overflow_reaction + and set_integer_overflow_reaction +- Remove block #ifndef MAX_INTEGER_OPERAND_SIZE, set definition of + MAX_INTEGER_OPERAND_SIZE to 128, since this is default +2016-05-10: +- Integrate new version of arithm library from ammunition repository from + dino repository on github (commit: db9cfab042c332abb234ec8d72750103010981c1), + which hanles arithmetic shifts by negative numbers. This change now makes all + test cases in ammunition.c pass. Update headers unsigned int bits => int bits +- Remove assert statements +- Fix memcmp implementation: dereferencing pointer was missing +- Add loop-bound annotation to memcmp +- Fix strcmp implementation +- Integrate working versions of memcpy and memset from pm benchmark +- Update signature of ammunition_memcpy to original version: + void *memcpy(void *dest, const void *src, size_x n); +- Move functions from libc into separate file, introduce header files + ammunition_limits.h, ammunition_stdio.h, ammunition_stdlib.h, + ammunition_string.h +- Fix overflow in sprintf_d: change datatype of variable 'copyOfNumber' from int + to long, since the negative value of INT_MIN is undefined + 2016-05-17: +- Remove all static declarations of global functions +- Rename variables 'digit_number' to digit_num to keep lines below 80 characters +- Rename op1_digit_number to op1_digit_number and op1_digit_num in function + 'ammunition_multiply_unsigned_integer_without_overflow_reaction' +- Rename variable 'scaled_op1_digit_number' in function + 'ammunition_divide_unsigned_integer_without_overflow_reaction' +- Apply code formatting with astyle + +2017-08-18: +- Add explicit casts to silence g++ warnings. diff --git a/baseline/source/ammunition/README b/baseline/source/ammunition/README new file mode 100644 index 0000000..8caddf4 --- /dev/null +++ b/baseline/source/ammunition/README @@ -0,0 +1,86 @@ +This directory AMMUNITION contains reusable packages on C/C++: +`allocate', `vlobject', `objstack', `hashtab', `commline', `ticker', +`position', `errors', `bits', `arithm', `IEEE': + o allocate + Allocating and freeing memory with automatic fixing some + allocation errors. + o vlobject + Work with variable length objects (VLO). Any number of bytes + may be added to and removed from the end of VLO. If it is + needed the memory allocated for storing variable length object + may be expanded possibly with changing the object place. But + between any additions of the bytes (or tailoring) the object + place is not changed. To decrease number of changes of the + object place the memory being allocated for the object is + longer than the current object length. + o objstack + Work with stacks of objects (OS). Work with the object on the + stack top is analogous to one with a variable length object. + One motivation for the package is the problem of growing char + strings in symbol tables. Memory for OS is allocated by + segments. A segment may contain more one objects. The most + recently allocated segment contains object on the top of OS. + If there is not sufficient free memory for the top object than + new segment is created and the top object is transferred into + the new segment, i.e. there is not any memory reallocation. + Therefore the top object may change its address. But other + objects never change address. + o hashtab + Work with hash tables. The package permits to work + simultaneously with several expandable hash tables. Besides + insertion and search of elements the elements from the hash + tables can be also removed. The table element can be only a + pointer. The size of hash tables is not fixed. The hash + table will be automatically expanded when its occupancy will + became big. + o position + Work with source code positions. The package serves to + support information about source positions of compiled files + taking all included files into account. + o errors + Output of compiler messages. The package serves output + one-pass or multi-pass compiler messages of various modes + (errors, warnings, fatal, system errors and appended messages) + in Unix style or for traditional listing. The package also + permits adequate error reporting for included files. + o commline + Work with command line. The package implements features + analogous to ones of public domain function `getopt'. The + goal of the package creation is to use more readable language + of command line description and to use command line + description as help output of program. + o ticker + Simultaneous work with several tickers (timers). + o bits + Work with bit strings (copying, moving, setting, testing, + comparison). + o arithm + Implementing host machine-independently arbitrary precision + integer numbers arithmetic. The implementation of the package + functions are not sufficiently efficient in order to use for + run-time. The package functions are oriented to implement + constant-folding in compilers, cross-compilers. + o IEEE + Implementing host machine-independently IEEE floating point + arithmetic. The implementation of the package functions are + not sufficiently efficient in order to use for run-time. The + package functions are oriented to implement constant-folding + in compilers, cross-compilers. + + There are files with corresponding names and extensions `.h' +(interface file for C/C++), `.c' (implementation file on C), and +`.cpp' (implementation file on C++). + + To install AMMUNITION see file INSTALL in the current directory. + + There are also shell scripts for testing the package with +corresponding names and extension `.tst'. Documentation of the +reusable packages is in files `ammunition.txt', `ammunition.dvi', +`ammunition.ps', `ammunition.info*', `ammunition*.html', +`ammunition*.rtf' for C and `ammunition++.txt', `ammunition++.dvi', +`ammunition++.ps', `ammunition++.info*', `ammunition++*.html', +`ammunition++*.rtf'. + +Please send bug reports and comments to vmakarov@fnmail.com + +Vladimir Makarov diff --git a/baseline/source/ammunition/ammunition.c b/baseline/source/ammunition/ammunition.c new file mode 100644 index 0000000..224babd --- /dev/null +++ b/baseline/source/ammunition/ammunition.c @@ -0,0 +1,1185 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: ammunition + + Author: Vladimir Makarov + + Function: Tests reusable packages bits and arith + bits: Work with bit strings (copying, moving, setting, testing, comparison). + arith: Implementing host machine-independently arbitrary precision integer + numbers arithmetic. The implementation of the package functions are not + sufficiently efficient in order to use for run-time. The package + functions are oriented to implement constant-folding in compilers, + cross-compilers. + + Source: DINO programming language repository + https://github.com/dino-lang/dino/ + + Changes: no major functional changes + + License: GPL 2 and LGPL 2 + +*/ + +#include "../extra.h" +#include "bits.h" +#include "arithm.h" +#include "ammunition_stdlib.h" +#include "ammunition_stdio.h" +#include "ammunition_string.h" + +/* + Forward declaration of functions +*/ + +void ammunition_reset_str_bits( char *str, char *s ); +void ammunition_reset_str_arithm( char *str, char *s, char *d, char *e, + char *g ); +int ammunition_bits_test(); +int ammunition_arithm_test(); +void ammunition_init( void ); +int ammunition_return( void ); +void ammunition_main( void ); +//int main( void ); + + +/* + Forward declaration of global variables +*/ + +int ammunition_result; + + +/* + Core functions +*/ + +void ammunition_reset_str_bits( char *str, char *s ) +{ + int i; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < 8; i++ ) { + str[i] = 0; + s[i] = 0; + } +} + + +void ammunition_reset_str_arithm( char *str, char *s, char *d, char *e, + char *g ) +{ + int i; + _Pragma( "loopbound min 20 max 20" ) + for ( i = 0; i < 20; i++ ) { + str[i] = 0; + s[i] = 0; + } + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < 4; i++ ) { + d[i] = 0; + e[i] = 0; + } + + _Pragma( "loopbound min 6 max 6" ) + for ( i = 0; i < 6; i++ ) + g[i] = 0; +} + + +int ammunition_bits_test() +{ + char str[8]; + char str1[8]; + + int result = 0; + unsigned int i, j; + + /* Test 1 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) { + if ( BIT ( str, i ) ) + result = 1; + } + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) { + SET_BIT ( str, i, 1 ); + _Pragma( "loopbound min 64 max 64" ) + for ( j = 0; j < sizeof ( str ) * CHAR_BIT; j++ ) + if ( j <= i ) { + if ( BIT ( str, j ) == 0 ) + result = 1; + } else + if ( BIT ( str, j ) ) + result = 1; + } + + /* Test 2 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < sizeof ( str ) * CHAR_BIT; i++ ) + if ( !ammunition_is_zero_bit_string ( + str, i, ( sizeof ( str ) * CHAR_BIT - i ) / 2 + 1 ) ) + result = 1; + ammunition_bit_string_set ( str, 13, 1, 35 ); + _Pragma( "loopbound min 13 max 13" ) + for ( i = 0; i < 13; i++ ) + if ( !ammunition_is_zero_bit_string ( str, i, 13 - i ) ) + result = 1; + _Pragma( "loopbound min 35 max 35" ) + for ( i = 13; i < 48; i++ ) + if ( ammunition_is_zero_bit_string ( str, i, 48 - i ) ) + result = 1; + _Pragma( "loopbound min 16 max 16" ) + for ( i = 48; i < sizeof ( str ) * CHAR_BIT; i++ ) + if ( !ammunition_is_zero_bit_string ( str, i, + sizeof ( str ) * CHAR_BIT - i ) ) + result = 1; + + /* Test 3 */ + ammunition_reset_str_bits( str, str1 ); + + _Pragma( "loopbound min 42 max 42" ) + for ( i = 0; i + i / 2 + 1 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, i, 1, i / 2 + 1 ); + if ( !ammunition_is_zero_bit_string ( str, 0, i - 1 ) ) + result = 1; + if ( ammunition_is_zero_bit_string ( str, i, i / 2 + 1 ) ) + result = 1; + if ( !ammunition_is_zero_bit_string ( + str, i + i / 2 + 1, sizeof ( str ) * CHAR_BIT - ( i + i / 2 + 1 ) ) ) + result = 1; + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + } + + /* Test 4 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 40 ); + _Pragma( "loopbound min 42 max 42" ) + for ( i = 0; i < 42; i++ ) + if ( ammunition_bit_string_comparison ( str, i, str1, i, 42 - i ) != 0 ) + result = 1; + _Pragma( "loopbound min 43 max 43" ) + for ( i = 0; i < 43; i++ ) + if ( ammunition_bit_string_comparison ( str, i, str1, i, + sizeof ( str ) * CHAR_BIT - i ) + <= 0 ) + result = 1; + _Pragma( "loopbound min 43 max 43" ) + for ( i = 0; i < 43; i++ ) + if ( ammunition_bit_string_comparison ( str1, i, str, i, + sizeof ( str ) * CHAR_BIT - i ) + >= 0 ) + result = 1; + + /* Test 5 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_copy ( str1, i + 5, str, i, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str1, i + 5, str, i, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + /* Test 6 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_move ( str, i + 5, str, i, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str, i + 5, str1, i, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + /* Test 7 */ + ammunition_reset_str_bits( str, str1 ); + + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_set ( str1, 2, 1, 43 ); + _Pragma( "loopbound min 59 max 59" ) + for ( i = 0; i + 5 < sizeof ( str ) * CHAR_BIT; i++ ) { + ammunition_bit_string_set ( str, 0, 0, sizeof ( str ) * CHAR_BIT ); + ammunition_bit_string_set ( str, 2, 1, 43 ); + ammunition_bit_string_move ( str, i, str, i + 5, + sizeof ( str ) * CHAR_BIT - i - 5 ); + if ( ammunition_bit_string_comparison ( + str, i, str1, i + 5, sizeof ( str ) * CHAR_BIT - i - 5 ) != 0 ) + result = 1; + } + + return result; +} + + +int ammunition_arithm_test() +{ + int result = 0; + + /* Test 1 */ + int i; + char str [20], s[20], d[4], e[4], g[6]; + + ammunition_integer_from_string ( 4, "-2147483649", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "2147483648", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + } + + /* Test 2 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "4294967296", d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + } + + /* Test 3 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MAX ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "1", e ); + ammunition_add_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX - 4 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 4 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_add_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, INT_MAX ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, i + 1 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_add_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i + 1 ) + result = 1; + } + + /* Test 4 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_unsigned_integer_from_string ( 4, "1", e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX - 4 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 4 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + ammunition_sprintf_u( str, UINT_MAX ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_add_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i + 1 ) + result = 1; + } + + /* Test 5 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MIN ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "1", e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN + 4 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 4 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, INT_MIN ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 10 - i ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_subtract_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i + i - 10 ) + result = 1; + } + + /* Test 6 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX - 2 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, UINT_MAX - 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_subtract_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_subtract_unsigned_integer ( 4, d, d, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_subtract_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i - i / 2 ) + result = 1; + } + + /* Test 7 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_d( str, INT_MAX / 2 + 1 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "2", e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MIN / 2 - 1 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_integer_from_string ( 4, "2", e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_d( str, INT_MAX / 3 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 3 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, ( INT_MAX / 3 ) * 3 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + ammunition_sprintf_d( str, INT_MIN / 2 ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, 2 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + ammunition_sprintf_d( str, ( INT_MIN / 2 ) * 2 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, i + 1000 ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_multiply_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i * ( i + 1000 ) ) + result = 1; + } + + /* Test 8 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_sprintf_u( str, UINT_MAX / 5 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 5 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_sprintf_u( str, UINT_MAX / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + ammunition_sprintf_u( str, ( UINT_MAX / 2 ) * 2 ); + if ( ammunition_strcmp ( s, str ) != 0 ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 2 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_multiply_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i * ( i / 2 ) ) + result = 1; + } + + /* Test 9 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "10", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_divide_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = -2000; i < 2000 ; i++ ) { + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_sprintf_d( str, ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ); + ammunition_integer_from_string ( 4, str, e ); + ammunition_divide_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_atoi ( s ) != i / ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ) + result = 1; + ammunition_sprintf_d( str, i ); + ammunition_integer_from_string ( 4, str, d ); + ammunition_divide_integer ( 4, d, e, e ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_atoi ( s ) != i / ( i < 0 ? - i / 20 + 1 : - i / 20 - 1 ) ) + result = 1; + } + + /* Test 10 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_divide_unsigned_integer ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 20 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_divide_unsigned_integer ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i / ( i / 20 + 1 ) ) + result = 1; + } + + /* Test 11 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_remainder ( 4, d, e, d ); + if ( !ammunition_overflow_bit ) + result = 1; + _Pragma( "loopbound min 4000 max 4000" ) + for ( i = 0; i < 4000 ; i++ ) { + ammunition_sprintf_u( str, i ); + ammunition_unsigned_integer_from_string ( 4, str, d ); + ammunition_sprintf_u( str, i / 20 + 1 ); + ammunition_unsigned_integer_from_string ( 4, str, e ); + ammunition_unsigned_integer_remainder ( 4, d, e, d ); + if ( ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_atoi ( s ) != i % ( i / 20 + 1 ) ) + result = 1; + } + + /* Test 12 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 0, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 32, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 8, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "5" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_right ( 4, d, 13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_left ( 4, d, -13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + + /* Test 13 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 32, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_right ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "5" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_right ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_left ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "16" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 32, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_right ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-6" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_right ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-17" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_left ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( !ammunition_overflow_bit || ammunition_strcmp ( s, "-17" ) != 0 ) + result = 1; + + /* Test 14 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 0, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 22, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 8, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "345088" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_left ( 4, d, 13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "134890", d ); + ammunition_unsigned_integer_shift_right ( 4, d, -13, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + + /* Test 15 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 21, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_shift_left ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "345088" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_left ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "134890", d ); + ammunition_integer_shift_right ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 0, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 21, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_shift_left ( 4, d, 8, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-345088" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_left ( 4, d, 13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1105018880" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-134890", d ); + ammunition_integer_shift_right ( 4, d, -13, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-1105018880" ) != 0 ) + result = 1; + + /* Test 16 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_eq_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_eq_integer ( 4, d, e ) ) + result = 1; + + /* Test 17 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_eq_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_eq_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 18 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ne_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_ne_integer ( 4, d, e ) ) + result = 1; + + /* Test 19 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ne_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_ne_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 20 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_gt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_gt_integer ( 4, d, e ) ) + result = 1; + + /* Test 21 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_gt_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 22 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_lt_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_integer ( 4, d, e ) ) + result = 1; + + /* Test 23 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_lt_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 24 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( ammunition_ge_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_integer ( 4, d, e ) ) + result = 1; + + /* Test 25 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_ge_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 26 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "-10", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1348", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "-1000000", d ); + ammunition_integer_from_string ( 4, "-1348", e ); + if ( !ammunition_le_integer ( 4, d, e ) ) + result = 1; + ammunition_integer_from_string ( 4, "1000000", d ); + ammunition_integer_from_string ( 4, "1348", e ); + if ( ammunition_le_integer ( 4, d, e ) ) + result = 1; + + /* Test 27 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "10", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( !ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1000000", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + if ( ammunition_le_unsigned_integer ( 4, d, e ) ) + result = 1; + + /* Test 28 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "70000", d ); + ammunition_change_unsigned_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "30000", d ); + ammunition_change_unsigned_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "30000" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "11230000", g ); + ammunition_change_unsigned_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "11230000" ) != 0 ) + result = 1; + + /* Test 29 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "40000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "-33000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + if ( !ammunition_overflow_bit ) + result = 1; + ammunition_integer_from_string ( 4, "30000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "30000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-30000", d ); + ammunition_change_integer_size ( 4, d, 2, d ); + ammunition_integer_to_string( 2, d, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-30000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "11230000", g ); + ammunition_change_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "11230000" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-11230000", g ); + ammunition_change_integer_size ( 4, g, 6, g ); + ammunition_integer_to_string( 6, g, s ); + if ( ammunition_overflow_bit || ammunition_strcmp ( s, "-11230000" ) != 0 ) + result = 1; + + /* Test 30 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "4294967295", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "4294967295" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "96", e ); + ammunition_unsigned_integer_or ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1380" ) != 0 ) + result = 1; + + /* Test 31 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "1348", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "-1", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "96", e ); + ammunition_integer_or ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1380" ) != 0 ) + result = 1; + + /* Test 32 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "1348", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "0", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "4294967295", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_from_string ( 4, "96", e ); + ammunition_unsigned_integer_and ( 4, d, e, e ); + ammunition_unsigned_integer_to_string ( 4, e, s ); + if ( ammunition_strcmp ( s, "64" ) != 0 ) + result = 1; + + /* Test 33 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "1348", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "0", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "-1", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "1348" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_from_string ( 4, "96", e ); + ammunition_integer_and ( 4, d, e, e ); + ammunition_integer_to_string( 4, e, s ); + if ( ammunition_strcmp ( s, "64" ) != 0 ) + result = 1; + + /* Test 34 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_unsigned_integer_from_string ( 4, "1348", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "4294965947" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "0", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "4294967295" ) != 0 ) + result = 1; + ammunition_unsigned_integer_from_string ( 4, "4294967295", d ); + ammunition_unsigned_integer_not ( 4, d, d ); + ammunition_unsigned_integer_to_string ( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + + /* Test 35 */ + ammunition_reset_str_arithm( str, s, d, e, g ); + + ammunition_integer_from_string ( 4, "1348", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "-1349" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "0", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "-1" ) != 0 ) + result = 1; + ammunition_integer_from_string ( 4, "-1", d ); + ammunition_integer_not ( 4, d, d ); + ammunition_integer_to_string( 4, d, s ); + if ( ammunition_strcmp ( s, "0" ) != 0 ) + result = 1; + + return result; +} + + +/* + Initialization- and return-value-related functions +*/ + +void ammunition_init( void ) +{ + ammunition_result = 0; +} + +int ammunition_return( void ) +{ + return ammunition_result; +} + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) ammunition_main( void ) +{ + ammunition_result |= ammunition_bits_test(); + ammunition_result |= ammunition_arithm_test(); +} + + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= '0' ) & ( c <= '9' ) ) + return 1; + else + return 0; +} + +int ammunition_isspace( int c ) +{ + return ( c == ' ' ) | ( c == '\t' ) | ( c == '\n' ) | ( c == '\r' ); +} + +void *ammunition_memcpy( void *dest, const void *src, size_x size ) +{ + size_x i; + _Pragma( "loopbound min 2 max 6" ) + for ( i = 0; i < size; i++ ) + ( ( unsigned char * )dest )[i] = ( ( unsigned char * )src )[i]; + + return dest; +} + + +void *ammunition_memset( void *s, int c, size_x n ) +{ + size_x i; + _Pragma( "loopbound min 0 max 4" ) + for ( i = 0; i < n; i++ ) + ( ( unsigned char * )s )[i] = ( unsigned char )c; + + return s; +} + + +int ammunition_memcmp ( const void *mem1, const void *mem2, size_x size ) +{ + const unsigned char *p1 = (const unsigned char *) mem1, + *p2 = (const unsigned char *) mem2; + _Pragma( "loopbound min 0 max 4" ) + while ( size-- ) + if ( *p1 != *p2 ) + return ( *p1 - *p2 ); + else + p1++, p2++; + return 0; +} + + +/* The following function is an analog of standard C function + `memmove'. The function returns the first operand. */ + +void *ammunition_memmove ( void *s1, const void *s2, size_x n ) +{ + int i; + + if ( ( ( char * ) s1 < ( char * ) s2 && ( char * ) s1 + n <= ( char * ) s2 ) + || ( ( char * ) s2 < ( char * ) s1 + && ( char * ) s2 + n <= ( char * ) s1 ) ) + return ( void * ) ammunition_memcpy ( s1, s2, n ); + if ( ( char * ) s1 < ( char * ) s2 && ( char * ) s1 + n > ( char * ) s2 ) { + _Pragma( "loopbound min 0 max 4" ) + for ( i = 0; ( size_x ) i < n; i++ ) + ( ( char * ) s1 ) [i] = ( ( char * ) s2 ) [i]; + } else { + _Pragma( "loopbound min 0 max 4" ) + for ( i = n - 1; i >= 0; i-- ) + ( ( char * ) s1 )[i] = ( ( char * ) s2 ) [i]; + } + return s1; +} + +int ammunition_strcmp ( const char *str1, const char *str2 ) +{ + _Pragma( "loopbound min 1 max 4008" ) + while ( *str1 && ( *str1 == *str2 ) ) + str1++, str2++; + return *( const unsigned char * )str1 - *( const unsigned char * )str2; +} + +int ammunition_atoi ( const char *str ) +{ + int result = 0; + int sign = ( str[0] == '-' ? -1 : 1 ); + + int readingPos = 0; + if ( str[0] == '-' || str[0] == '+' ) + readingPos++; + _Pragma( "loopbound min 1 max 1" ) + do { + result *= 10; + result += str[readingPos++] - 48; + } while ( str[readingPos] != 0 ); + + return sign * result; +} + + +int ammunition_sprintf_d( char *s, int number ) +{ + /* How many decimal digits do we need? */ + char digits = 0; + unsigned char writePos = 0; + long long copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + digits++; + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + writePos = digits; + if ( number < 0 ) { + writePos++; + s[0] = '-'; + } + s[writePos] = 0; + + copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + s[--writePos] = 48 + ( ( copyOfNumber >= 0 ? + copyOfNumber : -copyOfNumber ) % 10 ); + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + return digits + ( number < 0 ? 1 : 0 ); +} + + +int ammunition_sprintf_u( char *s, unsigned int number ) +{ + /* How many decimal digits do we need? */ + char digits = 0; + unsigned char writePos = 0; + unsigned long copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + digits++; + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + writePos = digits; + s[writePos] = 0; + + copyOfNumber = number; + _Pragma( "loopbound min 1 max 10" ) + do { + s[--writePos] = 48 + ( copyOfNumber % 10 ); + copyOfNumber /= 10; + } while ( copyOfNumber != 0 ); + + return digits; +} diff --git a/baseline/source/ammunition/ammunition_limits.h b/baseline/source/ammunition/ammunition_limits.h new file mode 100644 index 0000000..0de4c82 --- /dev/null +++ b/baseline/source/ammunition/ammunition_limits.h @@ -0,0 +1,35 @@ +#ifndef AMMUNITION_LIMITS_H +#define AMMUNITION_LIMITS_H + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif +#ifndef UCHAR_MAX +#define UCHAR_MAX 255 +#endif +#ifndef SCHAR_MAX +#define SCHAR_MAX 127 +#endif +#ifndef SCHAR_MIN +#define SCHAR_MIN (-128) +#endif +#ifndef USHRT_MAX +#define USHRT_MAX 65535 +#endif +#ifndef SHRT_MAX +#define SHRT_MAX 32767 +#endif +#ifndef SHRT_MIN +#define SHRT_MIN (-32768) +#endif +#ifndef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1) +#endif +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif +#ifndef INT_MIN +#define INT_MIN (-INT_MAX-1) +#endif + +#endif /* #ifndef AMMUNITION_LIMITS_H */ diff --git a/baseline/source/ammunition/ammunition_stdio.h b/baseline/source/ammunition/ammunition_stdio.h new file mode 100644 index 0000000..a3a7a4b --- /dev/null +++ b/baseline/source/ammunition/ammunition_stdio.h @@ -0,0 +1,8 @@ +#ifndef AMMUNITION_STDIO_H +#define AMMUNITION_STDIO_H + +int ammunition_sprintf_d( char *s, int number ); + +int ammunition_sprintf_u( char *s, unsigned int number ); + +#endif diff --git a/baseline/source/ammunition/ammunition_stdlib.h b/baseline/source/ammunition/ammunition_stdlib.h new file mode 100644 index 0000000..d907212 --- /dev/null +++ b/baseline/source/ammunition/ammunition_stdlib.h @@ -0,0 +1,6 @@ +#ifndef AMMUNITION_STDLIB_H +#define AMMUNITION_STDLIB_H + +int ammunition_atoi ( const char *str ); + +#endif diff --git a/baseline/source/ammunition/ammunition_string.h b/baseline/source/ammunition/ammunition_string.h new file mode 100644 index 0000000..6b042f8 --- /dev/null +++ b/baseline/source/ammunition/ammunition_string.h @@ -0,0 +1,18 @@ +#ifndef AMMUNITION_STRING_H +#define AMMUNITION_STRING_H + +typedef unsigned int size_x; +//typedef __SIZE_TYPE__ size_x; + +/* + Forward declaration of functions +*/ + +void *ammunition_memcpy( void *, const void *, size_x ); +void *ammunition_memset( void *, int, size_x ); +int ammunition_memcmp ( const void *mem1, const void *mem2, size_x size ); +void *ammunition_memmove ( void *s1, const void *s2, size_x n ); +int ammunition_strcmp ( const char *str1, const char *str2 ); + +#endif /* AMMUNITION_STRING_H */ + diff --git a/baseline/source/ammunition/arithm.c b/baseline/source/ammunition/arithm.c new file mode 100644 index 0000000..9480846 --- /dev/null +++ b/baseline/source/ammunition/arithm.c @@ -0,0 +1,1384 @@ +/* + FILE NAME: arithm.c + + TITLE: Package for arbitrary precision integer arithmetic + + DESCRIPTION: This abstract data implements arbitrary precision + integer and unsigned integer numbers by machine independent + way. The implementation of the package functions are not + sufficiently efficient in order to use for run-time. The + package functions are oriented to implement constant-folding in + compilers. This package is necessary because host machine may + not support such arithmetic for target machine. For example, + VAX does not support does not support more 32-bits integer + numbers arithmetic. The numbers are represented by bytes in + big endian mode, negative integer numbers are represented in + complementary code. All sizes are given in bytes and must be + positive. Results of executions of all functions can coincide + with a operand(s). All functions of addition, subtraction, + multiplication, division, evaluation of remainder, shift, + changing size and transformation of string into number fix + overflow. The overflow is fixed when result can not be + represented by number of given size. + +*/ + +#include "arithm.h" +#include "ammunition_string.h" + + +/* This variable can have only two values 0 or 1. The value `1' + corresponds to overflow. The variable value are modified by all + functions of addition, subtract, multiplication, division, + evaluation of remainder, shift, changing size and transformation of + string into number fix overflow. */ + +int ammunition_overflow_bit; + + +/* The following function adds unsigned integers. The function + returns 1 if unsigned integer overflow is fixed, 0 otherwise. + Result can be placed in any operand. */ + +int ammunition_add_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int digit_num; + int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + sum = ( ( ( unsigned char * ) op1 ) [digit_num] + + ( ( unsigned char * ) op2 ) [digit_num] + carry ); + if ( sum > UCHAR_MAX ) { + sum -= UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = sum; + } + return carry != 0; +} + +/* The following function adds unsigned integers. The function + returns 1 if unsigned integer overflow (the first operand is less + than the second) is fixed, 0 otherwise. Result can be placed in + any operand. */ + +int ammunition_subtract_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int digit_num; + int carry; + int subtraction; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + subtraction = ( ( ( unsigned char * ) op1 ) [digit_num] + - ( ( unsigned char * ) op2 ) [digit_num] - carry ); + if ( subtraction < 0 ) { + subtraction += UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = subtraction; + } + return carry != 0; +} + +/* The following function makes complementary code of number. Result + can be placed in operand. */ + +void ammunition_make_complementary_code +( int size, const void *operand, void *result ) +{ + int digit_num; + int carry; + int subtraction; + + _Pragma( "loopbound min 2 max 6" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + subtraction = ( 0 - ( ( unsigned char * ) operand ) [digit_num] - carry ); + if ( subtraction != 0 ) { + subtraction += UCHAR_MAX + 1; + carry = 1; + } else + carry = 0; + ( ( unsigned char * ) result ) [digit_num] = subtraction; + } +} + +/* The following function multiplys unsigned integer by digit (byte + size). The function returns 1 if unsigned integer overflow is + fixed, 0 otherwise. */ + +int ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction +( int size, void *operand, unsigned int digit ) +{ + int digit_num; + unsigned int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = 0; digit_num >= 0; digit_num-- ) { + sum = ( ( ( unsigned char * ) operand ) [digit_num] * digit + carry ); + if ( sum > UCHAR_MAX ) { + carry = sum / ( UCHAR_MAX + 1 ); + sum %= UCHAR_MAX + 1; + } else + carry = 0; + ( ( unsigned char * ) operand ) [digit_num] = sum; + } + return carry != 0; +} + + +/* Originally reaction on all integer and unsigned integer overflow is + equal to the following function. The function does nothing. */ + +void +ammunition_arithmetic_overflow_reaction ( void ) +{} + + +/* Originally reaction on all integer and unsigned integer overflow is + equal to the following function. The function does nothing. */ + +void +ammunition_arithmetic_unsigned_overflow_reaction ( void ) +{} + + +/* This page contains functions for arbitrary precision addition. */ + +/* The function adds unsigned integers and fixes overflow reaction if + it is needed. The function makes this with the aid of function + `add_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_add_unsigned_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_overflow_bit + = ammunition_add_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function adds integers and fixes overflow reaction if it is + needed. The function makes this with the aid of function + `add_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_add_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int op1_sign; + int sign_equality; + + op1_sign = INTEGER_SIGN ( op1 ); + sign_equality = INTEGER_SIGN ( op1 ) == INTEGER_SIGN ( op2 ); + ammunition_add_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + ammunition_overflow_bit = sign_equality && + ( op1_sign != INTEGER_SIGN ( result ) ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision subtraction. */ + +/* The function subtracts unsigned integers and fixes overflow + reaction if it is needed. The function makes this with the aid of + function `subtract_unsigned_integer_without_overflow_reaction'. + Result can be placed in any operand. */ + +void +ammunition_subtract_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ) +{ + ammunition_overflow_bit + = ammunition_subtract_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function subtracts integers and fixes overflow reaction if it + is needed. The function makes this with the aid of function + `subtract_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_subtract_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int op1_sign; + int sign_unequality; + + op1_sign = INTEGER_SIGN ( op1 ); + sign_unequality = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + ammunition_subtract_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + ammunition_overflow_bit = sign_unequality && + ( op1_sign != INTEGER_SIGN ( result ) ); + if ( ammunition_overflow_bit != 0 ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision multiplication. */ + +/* The following function multiplys unsigned integers. The function + returns 1 if unsigned integer overflow is fixed, 0 otherwise. + Result can be placed in any operand. */ + +int ammunition_multiply_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int op1_digit_num; + int op2_digit_num; + int carry; + unsigned long int partial_sum; + int result_digit_number; + int overflow_flag; + unsigned char long_result [2 * MAX_INTEGER_OPERAND_SIZE]; + + ammunition_memset ( long_result + size, 0, ( size_x ) size ); + _Pragma( "loopbound min 4 max 4" ) + for ( op2_digit_num = size - 1; op2_digit_num >= 0; op2_digit_num-- ) { + if ( ( ( unsigned char * ) op2 ) [op2_digit_num] != 0 ) { + _Pragma( "loopbound min 4 max 4" ) + for ( op1_digit_num = size - 1, carry = 0; op1_digit_num >= 0; + op1_digit_num-- ) { + partial_sum + = ( ( ( unsigned char * ) op1 ) [op1_digit_num] + * ( ( unsigned char * ) op2 ) [op2_digit_num] + + long_result [op1_digit_num + op2_digit_num + 1] + + carry ); + long_result [op1_digit_num + op2_digit_num + 1] + = ( unsigned char ) ( partial_sum % ( UCHAR_MAX + 1 ) ); + carry = partial_sum / ( UCHAR_MAX + 1 ); + } + long_result [op2_digit_num] = carry; + } else + long_result [op2_digit_num] = 0; + } + overflow_flag = 0; + _Pragma( "loopbound min 1 max 4" ) + for ( result_digit_number = size - 1; result_digit_number >= 0; + result_digit_number-- ) { + if ( long_result [result_digit_number] != 0 ) { + overflow_flag = 1; + break; + } + } + ammunition_memcpy ( result, long_result + size, ( size_x ) size ); + return overflow_flag; +} + +/* The following function multiplys unsigned integers and fixes + overflow reaction if it is needed. The function makes this with + the aid of function + `multiply_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_multiply_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ) +{ + ammunition_overflow_bit = + ammunition_multiply_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function multiplys integers and fixes overflow reaction if it + is needed. The function makes this with the aid of function + `multiply_unsigned_integer_without_overflow_reaction'. Result can + be placed in any operand. */ + +void +ammunition_multiply_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int negative_result_flag; + unsigned char op1_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned char op2_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned const char *abs_op1; + unsigned const char *abs_op2; + int unsigned_result_sign; + + negative_result_flag = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + if ( INTEGER_SIGN ( op1 ) ) { + /* May be integer overflow. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op1, op1_complementary ); + abs_op1 = ( unsigned const char * )op1_complementary; + } else + abs_op1 = ( unsigned const char * )op1; + if ( INTEGER_SIGN ( op2 ) ) { + /* May be integer overflow. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op2, op2_complementary ); + abs_op2 = ( unsigned const char * )op2_complementary; + } else + abs_op2 = ( unsigned const char * )op2; + ammunition_overflow_bit = + ammunition_multiply_unsigned_integer_without_overflow_reaction ( + size, abs_op1, abs_op2, result ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_result_flag ) + ammunition_make_complementary_code ( size, result, result ); + if ( unsigned_result_sign + && ( !negative_result_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ) + /* Unsigned result can not be represented as integer. */ + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision division. */ + +/* The following function divides unsigned integers. The function + returns 1 if unsigned integer overflow (division by zero) is fixed, + 0 otherwise. Result can be placed in any operand. See algorithm + in Knuth's book. */ + +int ammunition_divide_unsigned_integer_without_overflow_reaction +( int size, const void *op1, const void *op2, void *result ) +{ + int scaled_op1_digit_num; + unsigned int q_approximation; + int first_nonzero_digit_number; + int op2_digit_number; + unsigned int scale; + unsigned char scaled_op1 [MAX_INTEGER_OPERAND_SIZE + 1]; + unsigned char normalized_op2 [MAX_INTEGER_OPERAND_SIZE]; + unsigned char extended_normalized_op2 [MAX_INTEGER_OPERAND_SIZE + 1]; + + _Pragma( "loopbound min 4 max 4" ) + for ( op2_digit_number = 0; op2_digit_number < size; op2_digit_number++ ) { + if ( ( ( unsigned char * ) op2 ) [op2_digit_number] != 0 ) + break; + } + first_nonzero_digit_number = op2_digit_number; + if ( first_nonzero_digit_number == size ) { + /* Zero divisor */ + ammunition_memset ( result, 0, ( size_x ) size ); + return 1 /* TRUE */; + } else + if ( first_nonzero_digit_number == size - 1 ) { + /* Division by digit. */ + int digit_num; + int digit; + unsigned long divisable; + unsigned long remainder; + + digit = ( ( unsigned char * ) op2 ) [first_nonzero_digit_number]; + ammunition_memcpy ( result, op1, ( size_x ) size ); + remainder = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = 0; digit_num < size; digit_num++ ) { + divisable = ( remainder * ( UCHAR_MAX + 1 ) + + ( ( unsigned char * ) result ) [digit_num] ); + remainder = divisable % digit; + ( ( unsigned char * ) result ) [digit_num] + = ( unsigned char ) ( divisable / digit ); + } + return 0 /* FALSE */; + } + /* Normalization of divisor. */ + scale = ( UCHAR_MAX + 1 ) / ( ( ( unsigned char * ) op2 ) [op2_digit_number] + + 1 ); + ammunition_memcpy ( scaled_op1 + 1, op1, ( size_x ) size ); + *scaled_op1 = 0; + + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size + 1, scaled_op1, scale ); + + ammunition_memcpy ( normalized_op2, op2, ( size_x ) size ); + + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size, normalized_op2, scale ); + + _Pragma( "loopbound min 0 max 0" ) + for ( scaled_op1_digit_num = 0; + scaled_op1_digit_num <= first_nonzero_digit_number; + scaled_op1_digit_num++ ) { + /* Division of `scaled_op1[scaled_op1_digit_number]..scaled_op1[size]' by + `normalized_op2[first_nonzero_digit_number]..normalized_op2[size-1]' + for evaluation of one digit of quotient + `result[size-1-first_nonzero_digit_number-scaled_op1_digit_number]'. + */ + if ( scaled_op1 [scaled_op1_digit_num] + == normalized_op2 [first_nonzero_digit_number] ) + q_approximation = UCHAR_MAX; + else + q_approximation + = ( scaled_op1 [scaled_op1_digit_num] * ( UCHAR_MAX + 1 ) + + scaled_op1 [scaled_op1_digit_num + 1] ) + / normalized_op2 [first_nonzero_digit_number]; + + _Pragma( "loopbound min 0 max 0" ) + while ( normalized_op2 [first_nonzero_digit_number + 1] * q_approximation + > ( ( ( unsigned long int ) scaled_op1 [scaled_op1_digit_num] + * ( UCHAR_MAX + 1 ) + + scaled_op1 [scaled_op1_digit_num + 1] + - q_approximation + * normalized_op2 [first_nonzero_digit_number] ) + * ( UCHAR_MAX + 1 ) + scaled_op1 [scaled_op1_digit_num + 2] ) ) + q_approximation --; + + /* Multiply and subtract */ + ammunition_memcpy ( extended_normalized_op2 + 1, + normalized_op2 + first_nonzero_digit_number, + ( size_x ) ( size - first_nonzero_digit_number ) ); + *extended_normalized_op2 = 0; + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, extended_normalized_op2, + q_approximation ); + if ( ammunition_subtract_unsigned_integer_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, + scaled_op1 + scaled_op1_digit_num, extended_normalized_op2, + scaled_op1 + scaled_op1_digit_num ) ) { + /* Negative result. Compensation by addition. */ + q_approximation--; + ammunition_memcpy ( extended_normalized_op2 + 1, + normalized_op2 + first_nonzero_digit_number, + ( size_x ) ( size - first_nonzero_digit_number ) ); + *extended_normalized_op2 = 0; + + ammunition_add_unsigned_integer_without_overflow_reaction + ( size - first_nonzero_digit_number + 1, + scaled_op1 + scaled_op1_digit_num, extended_normalized_op2, + scaled_op1 + scaled_op1_digit_num ); + + } + ( ( unsigned char * ) result ) [size - 1 - first_nonzero_digit_number + + scaled_op1_digit_num] = q_approximation; + } + ammunition_memset ( result, 0, + ( size_x ) ( size - 1 - first_nonzero_digit_number ) ); + return 0 /* TRUE */; +} + +/* The function divides unsigned integers and fixes overflow reaction + if it is needed. The function makes this with the aid of function + `divide_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_divide_unsigned_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_overflow_bit = + ammunition_divide_unsigned_integer_without_overflow_reaction ( + size, op1, op2, result ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function divides integers and fixes overflow reaction if it is + needed. The function makes this with the aid of function + `divide_unsigned_integer_without_overflow_reaction'. Result can be + placed in any operand. */ + +void +ammunition_divide_integer ( int size, const void *op1, const void *op2, + void *result ) +{ + int negative_result_flag; + unsigned char op1_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned char op2_complementary [MAX_INTEGER_OPERAND_SIZE]; + unsigned const char *abs_op1; + unsigned const char *abs_op2; + int unsigned_result_sign; + + negative_result_flag = INTEGER_SIGN ( op1 ) != INTEGER_SIGN ( op2 ); + if ( INTEGER_SIGN ( op1 ) ) { + /* May be integer overflow for minimal int. But result is correct because + it is unsigned. */ + ammunition_make_complementary_code ( size, op1, op1_complementary ); + abs_op1 = ( unsigned const char * )op1_complementary; + } else + abs_op1 = ( unsigned const char * )op1; + if ( INTEGER_SIGN ( op2 ) ) { + /* May be integer overflow for minimal int. But result is correct + because it is unsigned. */ + ammunition_make_complementary_code ( size, op2, op2_complementary ); + abs_op2 = ( unsigned const char * )op2_complementary; + } else + abs_op2 = ( unsigned const char * )op2; + ammunition_overflow_bit = + ammunition_divide_unsigned_integer_without_overflow_reaction ( + size, abs_op1, abs_op2, result ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_result_flag ) + ammunition_make_complementary_code ( size, result, result ); + if ( unsigned_result_sign + && ( !negative_result_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ) + /* Unsigned result can not be represented as integer. */ + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for arbitrary precision evaluation of + remainder. */ + +/* The function evaluates remainder of division of unsigned integers + as `op1 - (op1/op2)*op2' and fixes overflow reaction if it is + needed. Result can be placed in any operand. */ + +void +ammunition_unsigned_integer_remainder ( int size, const void *op1, + const void *op2, + void *result ) +{ + unsigned char temporary [MAX_INTEGER_OPERAND_SIZE]; + + ammunition_divide_unsigned_integer ( size, op1, op2, temporary ); + if ( ammunition_overflow_bit ) + /* Reaction on zero is called from `divide_unsigned_integer'. */ + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_multiply_unsigned_integer ( size, temporary, op2, temporary ); + ammunition_subtract_unsigned_integer ( size, op1, temporary, result ); + } +} + + +/* This page contains functions for arbitrary precision number shifts. */ + +/* This function makes right shift of unsigned integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `unsigned_integer_shift_left'. The function fixes overflow when + result can not be represented by number of given size, i.e. in + other words the opposite unsigned shift (to left) results in number + not equal to source operand. Result can be placed in operand. */ + +void +ammunition_unsigned_integer_shift_right ( int size, const void *operand, + int bits, void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + + + if ( bits < 0 ) + ammunition_unsigned_integer_shift_left ( size, operand, -bits, result ); + else { + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 3" ) + for ( byte_number = ( byte_shift >= size ? 0 : size - byte_shift ); + byte_number < size; byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( ( char * ) result + byte_shift, operand, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( result, 0, ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 3 max 3" ) + for ( byte_number = byte_shift, carry = 0; byte_number < size; + byte_number++ ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte >> bit_shift ); + carry = ( byte << ( CHAR_BIT - bit_shift ) ) & UCHAR_MAX; + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + } +} + +/* This function makes right arithmetic shift of integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `integer_shift_left'. The function fixes overflow when result can + not be represented by number of given size, i.e. in other words the + opposite shift (to left) results in number not equal to source + operand. Result can be placed in operand. */ + +void +ammunition_integer_shift_right ( int size, const void *operand, int bits, + void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + int operand_sign; + + if ( bits < 0 ) + ammunition_integer_shift_left ( size, operand, -bits, result ); + else { + operand_sign = INTEGER_SIGN ( operand ); + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 3" ) + for ( byte_number = ( byte_shift >= size ? 0 : size - byte_shift ); + byte_number < size; byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, + ( operand_sign ? UCHAR_MAX : 0 ), ( size_x ) size ); + else { + ammunition_memmove ( ( char * ) result + byte_shift, operand, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( result, ( operand_sign ? UCHAR_MAX : 0 ), + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + carry = ( ( ( operand_sign ? UCHAR_MAX : 0 ) << ( CHAR_BIT - bit_shift ) ) + & UCHAR_MAX ); + _Pragma( "loopbound min 3 max 3" ) + for ( byte_number = byte_shift; byte_number < size; byte_number++ ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte >> bit_shift ); + carry = ( byte << ( CHAR_BIT - bit_shift ) ) & UCHAR_MAX; + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); + } +} + +/* This function makes left shift of unsigned integer of given size on + given number of bits. If number of bits is negative the function + makes shift to left actually with the aid of function + `unsigned_integer_shift_right'. The function fixes overflow when + result can not be represented by number of given size, i.e. i.e. in + other words the opposite shift (to right) results in number not + equal to source operand. Result can be placed in operand. */ + +void +ammunition_unsigned_integer_shift_left ( int size, const void *operand, + int bits, void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + + if ( bits < 0 ) + ammunition_unsigned_integer_shift_right ( size, operand, -bits, result ); + else { + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 2" ) + for ( byte_number = 0; byte_number < byte_shift && byte_number < size; + byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( result, ( char * ) operand + byte_shift, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( ( char * ) result + ( size - byte_shift ), 0, + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 2 max 3" ) + for ( byte_number = size - byte_shift - 1, carry = 0; + byte_number >= 0; byte_number-- ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte << bit_shift ); + carry = byte >> ( CHAR_BIT - bit_shift ); + } + if ( carry != 0 ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + } +} + +/* This function makes left arithmetic shift of integer of given size + on given number of bits. If number of bits is negative the + function makes shift to left actually with the aid of function + `integer_shift_right'. The function fixes overflow when result can + not be represented by number of given size, i.e. in other words the + opposite shift (to right) results in number not equal to source + operand. Result can be placed in operand. */ + +void +ammunition_integer_shift_left ( int size, const void *operand, int bits, + void *result ) +{ + int byte_number; + unsigned byte; + unsigned carry; + int bit_shift; + int byte_shift; + int operand_sign; + + if ( bits < 0 ) + ammunition_integer_shift_right ( size, operand, -bits, result ); + else { + operand_sign = INTEGER_SIGN ( operand ); + ammunition_overflow_bit = 0; + byte_shift = bits / CHAR_BIT; + bit_shift = bits % CHAR_BIT; + _Pragma( "loopbound min 0 max 2" ) + for ( byte_number = 0; byte_number < byte_shift && byte_number < size; + byte_number++ ) + if ( ( ( unsigned char * ) operand ) [byte_number] + != ( operand_sign ? UCHAR_MAX : 0 ) ) { + ammunition_overflow_bit = 1; + break; + } + if ( byte_shift >= size ) + ammunition_memset ( result, 0, ( size_x ) size ); + else { + ammunition_memmove ( result, ( char * ) operand + byte_shift, + ( size_x ) ( size - byte_shift ) ); + ammunition_memset ( ( char * ) result + ( size - byte_shift ), 0, + ( size_x ) byte_shift ); + if ( bit_shift == 0 ) + return; + _Pragma( "loopbound min 2 max 3" ) + for ( byte_number = size - byte_shift - 1, carry = 0; + byte_number >= 0; byte_number-- ) { + byte = ( ( unsigned char * ) result ) [byte_number]; + ( ( unsigned char * ) result ) [byte_number] + = carry | ( byte << bit_shift ); + carry = byte >> ( CHAR_BIT - bit_shift ); + } + if ( carry != ( ( unsigned ) ( operand_sign ? UCHAR_MAX : 0 ) + >> ( CHAR_BIT - bit_shift ) ) ) + ammunition_overflow_bit = 1; + } + if ( operand_sign != INTEGER_SIGN ( result ) ) + ammunition_overflow_bit = 1; + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); + } +} + + + +/* This page contains functions for bitwise operations of arbitrary + precision numbers. */ + +/* This function makes bitwise `or' of two integers of given size. */ + +void +ammunition_integer_or ( int size, const void *op1, const void *op2, + void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) op1 ) [byte_number] + | ( ( unsigned char * ) op2 ) [byte_number]; + } +} + +/* This function makes bitwise `or' of two unsigned integers of given + size. */ + +void +ammunition_unsigned_integer_or ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_integer_or ( size, op1, op2, result ); +} + + +/* This function makes bitwise `and' of two integers of given size. */ + +void +ammunition_integer_and ( int size, const void *op1, const void *op2, + void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) op1 ) [byte_number] + & ( ( unsigned char * ) op2 ) [byte_number]; + } +} + +/* This function makes bitwise `and' of two unsigned integers of given + size. */ + +void +ammunition_unsigned_integer_and ( int size, const void *op1, const void *op2, + void *result ) +{ + ammunition_integer_and ( size, op1, op2, result ); +} + + +/* This function makes bitwise `not' of integer of given size. */ + +void +ammunition_integer_not ( int size, const void *operand, void *result ) +{ + int byte_number; + + _Pragma( "loopbound min 4 max 4" ) + for ( byte_number = 0; byte_number < size; byte_number++ ) { + ( ( unsigned char * ) result ) [byte_number] + = ( ( unsigned char * ) operand ) [byte_number] ^ UCHAR_MAX; + } +} + +/* This function makes bitwise `not' of unsigned integer of given + size. */ + +void +ammunition_unsigned_integer_not ( int size, const void *operand, void *result ) +{ + ammunition_integer_not ( size, operand, result ); +} + + + +/* This page contains functions for comparison of arbitrary precision + numbers. */ + +/* This function compares two unsigned integers of given size on + equality. The function returns 1 if unsigned integers are equal, 0 + otherwise. */ + +int +ammunition_eq_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) == 0; +} + +/* This function compares two integers of given size on equality. The + function returns 1 if integers are equal, 0 otherwise. */ + +int +ammunition_eq_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) == 0; +} + +/* This function compares two unsigned integers of given size on + inequality. The function returns 1 if unsigned integers are not + equal, 0 otherwise. */ + +int +ammunition_ne_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) != 0; +} + +/* This function compares two integers of given size on inequality. + The function returns 1 if integers are not equal, 0 otherwise. */ + +int +ammunition_ne_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_memcmp ( op1, op2, ( size_x ) size ) != 0; +} + + +/* This function compares two memory parts of given size on that the + first operand is greater than the second. The bytes are described + as unsigned. The function returns 1 if the first operand is + greater than the second, - 1 if the first operand is less than the + second, 0 otherwise. */ + +int ammunition_bytes_comparison ( const void *op1, const void *op2, int size ) +{ + const unsigned char *str1 = ( unsigned const char * )op1; + const unsigned char *str2 = ( unsigned const char * )op2; + + _Pragma( "loopbound min 1 max 4" ) + while ( size > 0 && *str1 == *str2 ) { + str1++; + str2++; + size--; + } + if ( size <= 0 ) + return 0; + else + if ( *str1 > *str2 ) + return 1; + else + return -1; +} + +/* This function compares two unsigned integers of given size on that + the first operand is greater than the second. The function returns + 1 if the first unsigned integer is greater than the second, 0 + otherwise. */ + +int +ammunition_gt_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) > 0; +} + +/* This function compares two integers of given size on that the first + operand is greater than the second. The function returns 1 if the + first integer is greater than the second, 0 otherwise. */ + +int ammunition_gt_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) > 0; + else + return 1; /* TRUE */ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 0; /*FALSE*/ + else + return ammunition_bytes_comparison ( op1, op2, size ) > 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is less than the second. The function returns 1 + if the first unsigned integer is less than the second, 0 + otherwise. */ + +int +ammunition_lt_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) < 0; +} + +/* This function compares two integers of given size on that the first + operand is less than the second. The function returns 1 if the + first integer is less than the second, 0 otherwise. */ + +int +ammunition_lt_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) < 0; + else + return 0; /*FALSE*/ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 1; /* TRUE */ + else + return ammunition_bytes_comparison ( op1, op2, size ) < 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is greater than or equal to the second. The + function returns 1 if the first unsigned integer is greater than or + equal to the second, 0 otherwise. */ + +int +ammunition_ge_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; +} + +/* This function compares two integers of given size on that the first + operand is greater than or equal to the second. The function + returns 1 if the first integer is greater than or equal to the + second, 0 otherwise. */ + +int +ammunition_ge_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; + else + return 1; /* TRUE */ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 0; /*FALSE*/ + else + return ammunition_bytes_comparison ( op1, op2, size ) >= 0; +} + +/* This function compares two unsigned integers of given size on that + the first operand is less than or equal to the second. The + function returns 1 if the first unsigned integer is less than or + equal to the second, 0 otherwise. */ + +int +ammunition_le_unsigned_integer ( int size, const void *op1, const void *op2 ) +{ + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; +} + +/* This function compares two integers of given size on that the first + operand is less than or equal to the second. The function returns + 1 if the first integer is less than or equal to the second, 0 + otherwise. */ + +int +ammunition_le_integer ( int size, const void *op1, const void *op2 ) +{ + if ( INTEGER_SIGN ( op1 ) == 0 ) { + if ( INTEGER_SIGN ( op2 ) == 0 ) + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; + else + return 0; /*FALSE*/ + } else + if ( INTEGER_SIGN ( op2 ) == 0 ) + return 1; /* TRUE */ + else + return ammunition_bytes_comparison ( op1, op2, size ) <= 0; +} + + + +/* This page contains functions for changing size of arbitrary + precision numbers. */ + +/* The function changes size of unsigned integer. The function fixes + overflow when result can not be represented by number of given + size. Result can be placed in operand. */ + +void +ammunition_change_unsigned_integer_size ( int operand_size, const void *operand, + int result_size, void *result ) +{ + int operand_digit_number; + + ammunition_overflow_bit = 0; + if ( operand_size <= result_size ) { + ammunition_memmove ( ( char * ) result + result_size - operand_size, + operand, ( size_x ) operand_size ); + ammunition_memset ( result, 0, ( size_x ) ( result_size - operand_size ) ); + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( operand_digit_number = 0; + operand_digit_number < operand_size - result_size; + operand_digit_number++ ) { + if ( ( ( unsigned char * ) operand ) [operand_digit_number] != 0 ) { + ammunition_overflow_bit = 1; + break; + } + } + ammunition_memmove ( result, + ( char * ) operand + operand_size - result_size, + ( size_x ) result_size ); + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); +} + +/* The function changes size of integer. The function fixes overflow + when result can not be represented by number of given size. Result + can be placed in operand. */ + +void +ammunition_change_integer_size ( int operand_size, const void *operand, + int result_size, void *result ) +{ + int operand_digit_number; + int operand_sign; + + ammunition_overflow_bit = 0; + operand_sign = INTEGER_SIGN ( operand ); + if ( operand_size <= result_size ) { + ammunition_memmove ( ( char * ) result + result_size - operand_size, + operand, ( size_x ) operand_size ); + ammunition_memset ( result, ( operand_sign ? UCHAR_MAX : 0 ), + ( size_x ) ( result_size - operand_size ) ); + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( operand_digit_number = 0; + operand_digit_number < operand_size - result_size; + operand_digit_number++ ) { + if ( ( ( unsigned char * ) operand ) [operand_digit_number] + != ( operand_sign ? UCHAR_MAX : 0 ) ) { + ammunition_overflow_bit = 1; + break; + } + } + ammunition_memmove ( result, + ( char * ) operand + operand_size - result_size, + ( size_x ) result_size ); + if ( operand_sign != INTEGER_SIGN ( result ) ) + ammunition_overflow_bit = 1; + } + if ( ammunition_overflow_bit ) + ammunition_arithmetic_overflow_reaction(); +} + + + +/* This page contains functions for conversion of arbitrary precision + numbers to ascii representation. */ + +/* This function transforms unsigned integer of given size to BASE + ascii representation. BASE should be between 2 and 36 including + them. Digits more 9 are represented by 'a', 'b' etc. Sign is + absent in result string. The function returns the result + string. */ + +char * +ammunition_unsigned_integer_to_based_string ( int size, const void *operand, + int base, + char *result ) +{ + int digit_num; + int i; + unsigned long divisable; + unsigned long remainder; + int nonzero_flag; + int length; + int temporary; + unsigned char operand_copy [MAX_INTEGER_OPERAND_SIZE]; + + ammunition_memcpy ( operand_copy, operand, ( size_x ) size ); + length = 0; + _Pragma( "loopbound min 1 max 10" ) + do { + nonzero_flag = 0 /* FALSE */; + _Pragma( "loopbound min 2 max 6" ) + for ( digit_num = 0, remainder = 0; digit_num < size; digit_num++ ) { + divisable = remainder * ( UCHAR_MAX + 1 ) + operand_copy [digit_num]; + remainder = divisable % base; + operand_copy [digit_num] = ( unsigned char ) ( divisable / base ); + if ( operand_copy [digit_num] != 0 ) + nonzero_flag = 1 /* TRUE */; + } + result [length++] = ( unsigned char ) ( remainder < 10 ? '0' + remainder + : 'a' + remainder - 10 ); + } while ( nonzero_flag ); + result [length] = '\0'; + _Pragma( "loopbound min 0 max 5" ) + for ( i = 0; i < length / 2; i++ ) { + temporary = result [i]; + result [i] = result [length - i - 1]; + result [length - i - 1] = temporary; + } + return result; +} + + +/* This function transforms unsigned integer of given size to decimal + ascii representation. Sign is absent in result string. The + function returns the result string. */ + +char * +ammunition_unsigned_integer_to_string ( int size, const void *operand, + char *result ) +{ + return ammunition_unsigned_integer_to_based_string ( size, operand, 10, + result ); +} + + +/* This function transforms integer of given size to BASE ascii + representation. BASE should be between 2 and 36 including them. + Digits more 9 are represented by 'a', 'b' etc. Sign is present in + result string only for negative numbers. The function returns the + result string. */ + +char * +ammunition_integer_to_based_string ( int size, const void *operand, int base, + char *result ) +{ + unsigned char operand_copy [MAX_INTEGER_OPERAND_SIZE]; + + if ( !INTEGER_SIGN ( operand ) ) + return ammunition_unsigned_integer_to_based_string ( size, operand, base, + result ); + ammunition_memcpy ( operand_copy, operand, ( size_x ) size ); + /* May be integer overflow. But result is correct because it is unsigned. */ + ammunition_make_complementary_code ( size, operand_copy, operand_copy ); + *result = '-'; + ammunition_unsigned_integer_to_based_string ( size, operand_copy, base, + result + 1 ); + return result; +} + + + +/* This function transforms integer of given size to decimal ascii + representation. Sign is present in result string only for negative + numbers. The function returns the result string. */ + +char * +ammunition_integer_to_string ( int size, const void *operand, char *result ) +{ + return ammunition_integer_to_based_string ( size, operand, 10, result ); +} + +/* This page contains functions for conversion of decimal ascii + representation to arbitrary precision numbers. */ + +/* The function adds digit (byte size) to unsigned integer. The + function returns 1 if unsigned integer overflow is fixed, 0 + otherwise. */ + +int ammunition_add_digit_to_unsigned_integer_without_overflow_reaction +( int size, void *operand, unsigned int digit ) +{ + int digit_num; + unsigned int carry; + unsigned int sum; + + _Pragma( "loopbound min 4 max 4" ) + for ( digit_num = size - 1, carry = digit; digit_num >= 0; + digit_num-- ) { + sum = ( ( unsigned char * ) operand ) [digit_num] + carry; + if ( sum > UCHAR_MAX ) { + carry = sum / ( UCHAR_MAX + 1 ); + sum %= UCHAR_MAX + 1; + } else + carry = 0; + ( ( unsigned char * ) operand ) [digit_num] = sum; + } + return carry != 0; +} + +/* This function transforms source string (decimal ascii + representation without sign) to given size unsigned integer and + returns pointer to first non digit in the source string through a + parameter. If the string started with invalid integer + representation the result will be zero and returns the operand + through the parameter. The function returns 1 if unsigned integer + overflow is fixed, 0 otherwise. */ + +int ammunition_string_to_unsigned_integer_without_overflow_reaction +( int size, const char *operand, void *result, char **first_nondigit ) +{ + int overflow_flag; + + ammunition_memset ( result, 0, ( size_x ) size ); + _Pragma( "loopbound min 0 max 10" ) + for ( overflow_flag = 0; ammunition_isdigit ( *operand ); operand++ ) { + overflow_flag + = overflow_flag || + ammunition_multiply_unsigned_integer_by_digit_without_overflow_reaction + ( size, result, 10 ); + overflow_flag + = overflow_flag + || ammunition_add_digit_to_unsigned_integer_without_overflow_reaction + ( size, result, *operand - '0' ); + } + *first_nondigit = ( char * ) operand; + return overflow_flag; +} + +/* This function skips all white spaces at the begin of source string + and transforms tail of the source string (decimal ascii + representation without sign) to given size unsigned integer with + the aid of function + `string_to_unsigned_integer_without_overflow_reaction'. If the + string started with invalid unsigned integer representation the + result will be zero. The function fixes overflow when result can + not be represented by number of given size. The function returns + address of the first nondigit in the source string. */ + +char * +ammunition_unsigned_integer_from_string ( int size, const char *operand, + void *result ) +{ + char *first_nondigit; + + _Pragma( "loopbound min 0 max 0" ) + while ( ammunition_isspace ( *operand ) ) + operand++; + ammunition_overflow_bit + = ammunition_string_to_unsigned_integer_without_overflow_reaction + ( size, operand, result, &first_nondigit ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + return first_nondigit; +} + +/* This function skips all white spaces at the begin of source string + and transforms tail of the source string (decimal ascii + representation with possible sign `+' or `-') to given size integer + with the aid of function + `string_to_unsigned_integer_without_overflow_reaction'. If the + string started with invalid integer representation the result will + be zero. The function fixes overflow when result can not be + represented by number of given size. the function returns Address + of the first nondigit in the source string. */ + +char * +ammunition_integer_from_string ( int size, const char *operand, void *result ) +{ + int negative_number_flag; + char *first_nondigit; + int unsigned_result_sign; + + _Pragma( "loopbound min 0 max 0" ) + while ( ammunition_isspace ( *operand ) ) + operand++; + negative_number_flag = 0; /* FALSE */ + if ( *operand == '+' ) + operand++; + else + if ( *operand == '-' ) { + operand++; + negative_number_flag = 1; /* TRUE */ + } + ammunition_overflow_bit + = ammunition_string_to_unsigned_integer_without_overflow_reaction + ( size, operand, result, &first_nondigit ); + unsigned_result_sign = INTEGER_SIGN ( result ); + if ( negative_number_flag ) + /* May be integer overflow when `result' is correct. But result + is correct because it is unsigned. */ + ammunition_make_complementary_code ( size, result, result ); + ammunition_overflow_bit + = ammunition_overflow_bit + || ( unsigned_result_sign + && ( !negative_number_flag + || INTEGER_SIGN ( result ) != unsigned_result_sign ) ); + if ( ammunition_overflow_bit ) + ammunition_arithmetic_unsigned_overflow_reaction(); + return first_nondigit; +} + diff --git a/baseline/source/ammunition/arithm.h b/baseline/source/ammunition/arithm.h new file mode 100644 index 0000000..8ed78bf --- /dev/null +++ b/baseline/source/ammunition/arithm.h @@ -0,0 +1,123 @@ +/* + FILE NAME: arithm.h + + TITLE: Include file of package for arbitrary precision integer + arithmetic + + DESCRIPTION: This header file contains ANSI C prototype definitions of + the package functions and definitions of external + variable of the package and C++ classes for arbitrary + precision integer arithmetic. + +*/ + + +#ifndef __ARITHMETIC__ +#define __ARITHMETIC__ + +#include "ammunition_limits.h" + + +/* This page contains definitions of variables and macros common for + all package functions. */ + +/* The value of macro is suggested to be maximum length of integer operands + The length of use integers should be not greater than this value. */ + +#define MAX_INTEGER_OPERAND_SIZE 128 + +/* The following macro value is sign of integer number (0 or 1) given + as macro parameter. */ + +#define INTEGER_SIGN(operand) (*(unsigned char *) (operand) >> (CHAR_BIT - 1)) + +extern int ammunition_overflow_bit; + +extern void ammunition_add_unsigned_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_add_integer ( int size, const void *op1, const void *op2, + void *result ); +extern void ammunition_subtract_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_subtract_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_multiply_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_multiply_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_divide_unsigned_integer ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_divide_integer ( int size, const void *op1, + const void *op2, + void *result ); +extern void ammunition_unsigned_integer_remainder ( int size, const void *op1, + const void *op2, void *result ); + +extern void ammunition_unsigned_integer_shift_right ( int size, + const void *operand, + int bits, void *result ); +extern void ammunition_integer_shift_right ( int size, const void *operand, + int bits, void *result ); +extern void ammunition_integer_shift_left ( int size, const void *operand, + int bits, void *result ); +extern void ammunition_unsigned_integer_shift_left ( int size, + const void *operand, + int bits, void *result ); + +extern void ammunition_integer_or ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_unsigned_integer_or ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_integer_and ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_unsigned_integer_and ( int size, const void *op1, + const void *op2, void *result ); +extern void ammunition_integer_not ( int size, const void *operand, + void *result ); +extern void ammunition_unsigned_integer_not ( int size, const void *operand, + void *result ); + +extern int ammunition_eq_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_eq_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_ne_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_ne_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_gt_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_gt_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_lt_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_lt_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_ge_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_ge_integer ( int size, const void *op1, const void *op2 ); +extern int ammunition_le_unsigned_integer ( int size, const void *op1, + const void *op2 ); +extern int ammunition_le_integer ( int size, const void *op1, const void *op2 ); + +extern void ammunition_change_unsigned_integer_size +( int operand_size, const void *operand, int result_size, void *result ); +extern void ammunition_change_integer_size ( int operand_size, + const void *operand, + int result_size, void *result ); + +extern char *ammunition_unsigned_integer_to_string ( int size, + const void *operand, + char *result ); +extern char *ammunition_integer_to_string ( int size, const void *operand, + char *result ); + +extern char *ammunition_unsigned_integer_from_string ( int size, + const char *operand, + void *result ); +extern char *ammunition_integer_from_string ( int size, const char *operand, + void *result ); + +char ammunition_isdigit( unsigned char c ); +int ammunition_isspace( int c ); + +#endif /* #ifndef __ARITHMETIC__ */ diff --git a/baseline/source/ammunition/bits.c b/baseline/source/ammunition/bits.c new file mode 100644 index 0000000..9169656 --- /dev/null +++ b/baseline/source/ammunition/bits.c @@ -0,0 +1,313 @@ +/* + + FILE NAME: bits.c + + TITLE: Package for work with bits + + DESCRIPTION: This file implements functions of the package for work + with bit strings. A bit is given by address (start address) of + byte from which counting bits starts and its displacement which + is any non negative number of bit from the start address. The + most significant bit of the start address byte has number 0. + The bit string is given by its first bit and its length in + bits. + +*/ + +#include "bits.h" + +/* This function determines that given bit string contains only zero + bits. The function retruns TRUE if all bits of given bit string + are zero or `bit_length' <= 0. Value of `bit_displacement' must be + non-negative and can be greater than CHAR_BIT. */ + +int +ammunition_is_zero_bit_string ( const void *start_byte, int bit_displacement, + int bit_length ) +{ + const unsigned char *current_byte = ( unsigned const char * )start_byte; + + if ( bit_length <= 0 ) + return 1 /* TRUE */; + current_byte += bit_displacement / CHAR_BIT; + bit_displacement %= CHAR_BIT; + if ( bit_length < CHAR_BIT - bit_displacement ) + return ( ( ( *current_byte << bit_displacement ) + & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ) + & UCHAR_MAX ) == 0; + else + if ( bit_displacement != 0 ) { + if ( ( ( *current_byte << bit_displacement ) & UCHAR_MAX ) != 0 ) + return 0 /* FALSE */; + current_byte += 1; + bit_length -= CHAR_BIT - bit_displacement; + } + _Pragma( "loopbound min 0 max 7" ) + while ( bit_length >= CHAR_BIT ) { + if ( *current_byte != 0 ) + return 0 /* FALSE */; + current_byte++; + bit_length -= CHAR_BIT; + } + if ( bit_length > 0 && ( *current_byte >> ( CHAR_BIT - bit_length ) ) != 0 ) + return 0 /* FALSE */; + return 1 /* TRUE */; +} + +/* This function sets up new value of all bits of given bit string. + This function is analog of standard C function `memset'. Value of + `bit_displacement' must be non-negative and can be greater than + CHAR_BIT. */ + +void +ammunition_bit_string_set ( void *start_byte, int bit_displacement, int bit, + int bit_length ) +{ + unsigned char *current_byte = ( unsigned char * )start_byte; + unsigned char filling_byte; + int mask; + + if ( bit_length <= 0 ) + return ; + bit = bit != 0; /* 1 or 0 */ + filling_byte = ( bit ? UCHAR_MAX : 0 ); + current_byte += bit_displacement / CHAR_BIT; + bit_displacement %= CHAR_BIT; + if ( bit_displacement != 0 ) { + mask = UCHAR_MAX << ( CHAR_BIT - bit_displacement ); + if ( bit_length < CHAR_BIT - bit_displacement ) + mask |= UCHAR_MAX >> ( bit_displacement + bit_length ); + *current_byte = ( *current_byte & mask ) | ( filling_byte & ~mask ); + current_byte += 1; + bit_length -= CHAR_BIT - bit_displacement; + } + _Pragma( "loopbound min 0 max 8" ) + while ( bit_length >= CHAR_BIT ) { + *current_byte = filling_byte; + current_byte++; + bit_length -= CHAR_BIT; + } + if ( bit_length > 0 ) + *current_byte + = ( *current_byte & ~( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ) + | ( filling_byte & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string. This + function is analog of standard C function `memcpy'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string must + be non-overlapped. */ + +void +ammunition_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + int byte; + int mask; + + if ( bit_length <= 0 ) + return ; + current_to_byte += to_bit_displacement / CHAR_BIT; + to_bit_displacement %= CHAR_BIT; + current_from_byte += from_bit_displacement / CHAR_BIT; + from_bit_displacement %= CHAR_BIT; + _Pragma( "loopbound min 1 max 8" ) + while ( 1 ) { + byte = ( ( ( *current_from_byte << from_bit_displacement ) & UCHAR_MAX ) + | ( from_bit_displacement != 0 + && bit_length > ( CHAR_BIT - from_bit_displacement ) + ? current_from_byte [1] >> ( CHAR_BIT - from_bit_displacement ) + : 0 ) ); + if ( bit_length <= CHAR_BIT ) + break; + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + *current_to_byte + = ( *current_to_byte + & ( UCHAR_MAX << ( CHAR_BIT - to_bit_displacement ) ) ) + | ( byte >> to_bit_displacement ); + if ( to_bit_displacement != 0 ) + current_to_byte [1] + = ( current_to_byte [1] & ( UCHAR_MAX >> to_bit_displacement ) ) + | ( byte << ( CHAR_BIT - to_bit_displacement ) ); + bit_length -= CHAR_BIT; + current_from_byte++; + current_to_byte++; + } + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + mask = ( ( UCHAR_MAX << ( CHAR_BIT - to_bit_displacement ) ) + | ( UCHAR_MAX >> ( to_bit_displacement + bit_length ) ) ); + *current_to_byte + = ( *current_to_byte & mask ) | ( ( byte >> to_bit_displacement ) & ~mask ); + bit_length -= CHAR_BIT - to_bit_displacement; + if ( bit_length > 0 ) + current_to_byte [1] + = ( current_to_byte [1] & ( UCHAR_MAX >> bit_length ) ) + | ( ( byte << ( CHAR_BIT - to_bit_displacement ) ) + & ( UCHAR_MAX << ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string. Copying + starts with the last bits of the bit strings. This function is + used by function `bit_string_move'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string must + be non-overlapped. */ + +void ammunition_reverse_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + int byte; + int mask; + + if ( bit_length <= 0 ) + return ; + to_bit_displacement += bit_length - 1; + current_to_byte += to_bit_displacement / CHAR_BIT; /* last byte */ + to_bit_displacement %= CHAR_BIT; /* last bit */ + from_bit_displacement += bit_length - 1; + current_from_byte += from_bit_displacement / CHAR_BIT; /* last byte */ + from_bit_displacement %= CHAR_BIT; /* last bit */ + _Pragma( "loopbound min 1 max 8" ) + while ( 1 ) { + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + byte = ( ( *current_from_byte >> ( CHAR_BIT - 1 - from_bit_displacement ) ) + | ( ( from_bit_displacement != CHAR_BIT - 1 + && bit_length > from_bit_displacement + 1 + ? current_from_byte [ -1 ] << ( from_bit_displacement + 1 ) + : 0 ) + & UCHAR_MAX ) ); + if ( bit_length <= CHAR_BIT ) + break; + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + *current_to_byte + = ( *current_to_byte & ( UCHAR_MAX >> ( to_bit_displacement + 1 ) ) ) + | ( byte << ( CHAR_BIT - 1 - to_bit_displacement ) ); + if ( to_bit_displacement != CHAR_BIT - 1 ) + current_to_byte [-1] + = ( current_to_byte [-1] + & ( UCHAR_MAX << ( CHAR_BIT - 1 - to_bit_displacement ) ) ) + | ( byte >> ( to_bit_displacement + 1 ) ); + bit_length -= CHAR_BIT; + current_from_byte--; + current_to_byte--; + } + /* Shift is correct when to_bit_displacement == 0 because its + value is less than word bit size. */ + mask = ( ( UCHAR_MAX >> ( to_bit_displacement + 1 ) ) | + ( UCHAR_MAX << ( CHAR_BIT - 1 - to_bit_displacement + + bit_length ) ) ); + *current_to_byte + = ( *current_to_byte & mask ) + | ( ( byte << ( CHAR_BIT - 1 - to_bit_displacement ) ) & ~mask ); + bit_length -= to_bit_displacement + 1; + if ( bit_length > 0 ) + current_to_byte [-1] + = ( current_to_byte [-1] & ( UCHAR_MAX << bit_length ) ) + | ( byte >> ( to_bit_displacement + 1 ) + & ( UCHAR_MAX >> ( CHAR_BIT - bit_length ) ) ); +} + +/* This function copys a bit string to another bit string with the aid + of functions `bit_string_copy' and `reverse_bit_string_copy'. This + function is analog of standard C function `memmove'. Values of + `to_bit_displacement' and `from_bit_displacement' must be + non-negative and can be greater than CHAR_BIT. The bit string can + be overlapped. */ + +void +ammunition_bit_string_move ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ) +{ + unsigned char *current_to_byte = ( unsigned char * )to; + const unsigned char *current_from_byte = ( unsigned const char * )from; + + if ( bit_length <= 0 ) + return ; + current_to_byte += to_bit_displacement / CHAR_BIT; + to_bit_displacement %= CHAR_BIT; + current_from_byte += from_bit_displacement / CHAR_BIT; + from_bit_displacement %= CHAR_BIT; + if ( current_from_byte > current_to_byte + || ( current_from_byte == current_to_byte + && from_bit_displacement > to_bit_displacement ) ) + ammunition_bit_string_copy ( current_to_byte, to_bit_displacement, + current_from_byte, from_bit_displacement, + bit_length ); + else + ammunition_reverse_bit_string_copy ( current_to_byte, to_bit_displacement, + current_from_byte, + from_bit_displacement, bit_length ); +} + +/* This function compares bit strings. This function is analog of + standard C function `memcmp'. The function returns 0 if the bit + strings are equal, 1 if the first bit string is greater than the + second, -1 if the first bit string is less than the first. Values + of `bit_displacement1' and `bit_displacement2' must be non-negative + and can be greater than CHAR_BIT. */ + +int +ammunition_bit_string_comparison ( const void *str1, int bit_displacement1, + const void *str2, int bit_displacement2, + int bit_length ) +{ + const unsigned char *current_byte1 = ( unsigned const char * )str1; + const unsigned char *current_byte2 = ( unsigned const char * )str2; + int byte1; + int byte2; + int mask; + + if ( bit_length <= 0 ) + return 0; + current_byte1 += bit_displacement1 / CHAR_BIT; + bit_displacement1 %= CHAR_BIT; + current_byte2 += bit_displacement2 / CHAR_BIT; + bit_displacement2 %= CHAR_BIT; + _Pragma( "loopbound min 1 max 284" ) + while ( 1 ) { + byte1 = ( ( ( *current_byte1 << bit_displacement1 ) & UCHAR_MAX ) + | ( bit_displacement1 != 0 + /* Shift is correct when to_bit_displacement == 0 + because its value is less than word bit size. */ + && bit_length > CHAR_BIT - bit_displacement1 + ? current_byte1 [1] >> ( CHAR_BIT - bit_displacement1 ) + : 0 ) ); + byte2 = ( ( ( *current_byte2 << bit_displacement2 ) & UCHAR_MAX ) + | ( bit_displacement2 != 0 + && bit_length > CHAR_BIT - bit_displacement2 + ? current_byte2 [1] >> ( CHAR_BIT - bit_displacement2 ) + : 0 ) ); + if ( bit_length <= CHAR_BIT ) + break; + if ( byte1 > byte2 ) + return 1; + else + if ( byte1 < byte2 ) + return -1; + bit_length -= CHAR_BIT; + current_byte2++; + current_byte1++; + } + /* Shift is correct when to_bit_displacement == 0 because its value + is less than word bit size. */ + mask = UCHAR_MAX << ( CHAR_BIT - bit_length ); + if ( ( byte1 & mask ) > ( byte2 & mask ) ) + return 1; + else + if ( ( byte1 & mask ) < ( byte2 & mask ) ) + return -1; + else + return 0; +} diff --git a/baseline/source/ammunition/bits.h b/baseline/source/ammunition/bits.h new file mode 100644 index 0000000..70cf8bd --- /dev/null +++ b/baseline/source/ammunition/bits.h @@ -0,0 +1,60 @@ +/* + FILE NAME: bits.h + + TITLE: Include file of package for work with bits + + DESCRIPTION: + This is header file contains macros and the ANSI C prototype + definitions for the package for work with bits and bit strings + and C++ class for work with bits and bit strings. A bit is + given by address (start address) of byte from which counting + bits starts and its displacement which is any non negative + number of bit from the start address. The most significant bit + of the start address byte has number 0. The bit string is + given by its first bit and its length in bits. + +*/ + +#ifndef __BITS__ +#define __BITS__ + +#include "ammunition_limits.h" + +/* This macro value returns bit vlaue (0 or 1) with given bit + displacement (0, 1, ...). The macro has side effects! Value of + `bit_displacement' must be nonegative and can be greater than + CHAR_BIT. */ + +#define BIT(start_byte, bit_displacement)\ + ((((const char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + >> (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)) & 1) + + +/* This macro value sets up new value (must be `0' or `1') of a given + bit (bit displacement starts with 0). The macro has side effects! + Value of `bit_displacement' must be nonegative and can be greater + than CHAR_BIT. */ + +#define SET_BIT(start_byte, bit_displacement, bit)\ + (((char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + = (((char *) (start_byte)) [(bit_displacement) / CHAR_BIT]\ + & ~(1 << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT)))\ + | ((bit) << (CHAR_BIT - 1 - (bit_displacement) % CHAR_BIT))) + +int ammunition_is_zero_bit_string ( const void *start_byte, + int bit_displacement, + int bit_length ); +void ammunition_bit_string_set ( void *start_byte, int bit_displacement, + int bit, + int bit_length ); +void ammunition_bit_string_copy ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ); +void ammunition_bit_string_move ( void *to, int to_bit_displacement, + const void *from, int from_bit_displacement, + int bit_length ); +int ammunition_bit_string_comparison ( const void *str1, int bit_displacement1, + const void *str2, int bit_displacement2, + int bit_length ); + +#endif /* #ifndef __BITS__ */ diff --git a/baseline/source/ammunition/gmon.out b/baseline/source/ammunition/gmon.out new file mode 100644 index 0000000..2d07b7f Binary files /dev/null and b/baseline/source/ammunition/gmon.out differ diff --git a/baseline/source/ammunition/timeScript b/baseline/source/ammunition/timeScript new file mode 100644 index 0000000..33ba812 --- /dev/null +++ b/baseline/source/ammunition/timeScript @@ -0,0 +1,8 @@ +#!/bin/bash +startTime=$(date +%N) +echo start time $startTime +$1 +stopTime=$(date +%N) +echo stop time $stopTime +totalTime=`expr $stopTime - $startTime` +echo total time $totalTime diff --git a/baseline/source/anagram/ChangeLog.txt b/baseline/source/anagram/ChangeLog.txt new file mode 100644 index 0000000..fdba1cc --- /dev/null +++ b/baseline/source/anagram/ChangeLog.txt @@ -0,0 +1,125 @@ +File: anagram.c +Original provenience: unknown +Source: unknown + +2017-04-18: +- Annotated anagram_main as entry-point for timing analysis + +2016-06-22: +- Fixed type signature of function anagram_main to conform to TACLeBench + standard, i.e. `void anagram_main (void)`. + +2016-05-24: +- Changed type of global variables anagram_achPhrase and + anagram_dictionary to `char const *[]`. +- Changed parameter type of function anagram_BuildMask to + `char const *`. + +2016-04-26: +- Fixed array out-of-bounds access introduced by earlier change. + +2016-04-20: +- Fixed some compiler warnings. +- Return value of anagram_return depends on the computation inside + of anagram_main. + +2016-03-22 +- Added forward declarations for all functions. +- Renamed function main to anagram_main. +- Added function anagram_init that calls anagram_ReadDict, removed + call to anagram_ReadDict from anagram_main. +- Added function anagram_return that handles the return value. +- Added new function main that first calls anagram_init, + then anagram_main and finally returns the return value of + anagram_return. +- Added generic TACLeBench header to all files. +- Introduced comments to split file in sections for type + definitions, forward declarations, global variables, + initialization-related and return-value-related functions, + core benchmark functions, and main routine. +- Renamed ch2i, DICTWORDS, Quad, MASK_BITS, MAX_QUADS, MAXCAND, + MAXSOL, ALPHABET, Word, PWord, PPWord, apwCand, cpwCand, Letter, + PLetter, alPhrase, cchPhraseLength, aqMainMask, aqMainSign, + cchMinLength, auGlobalFrequency, achByFrequency, pchDictionary, + Reset, ReadDict, BuildMask, NewWord, NextWord, BuildWord, + AddWords, apwSol, cpwLast, OneStep, DumpWords, FindAnagram and + SortCandidates to anagram_ch2i, anagram_DICTWORDS, anagram_Quad, + anagram_MASK_BITS, anagram_MAX_QUADS, anagram_MAXCAND, + anagram_MAXSOL, anagram_ALPHABET, anagram_Word, anagram_PWord, + anagram_PPWord, anagram_apwCand, anagram_cpwCand, anagram_Letter, + anagram_PLetter, anagram_alPhrase, anagram_cchPhraseLength, + anagram_aqMainMask, anagram_aqMainSign, anagram_cchMinLength, + anagram_auGlobalFrequency, anagram_achByFrequency, + anagram_pchDictionary, anagram_Reset, anagram_ReadDict, + anagram_BuildMask, anagram_NewWord, anagram_NextWord, + anagram_BuildWord, anagram_AddWords, anagram_apwSol, + anagram_cpwLast, anagram_OneStep, anagram_DumpWords, + anagram_FindAnagram and anagram_SortCandidates. +- Renamed swapi, pivot, qsorts, simulated_heap and freeHeapPos to + anagram_swapi, anagram_pivot, anagram_qsorts, + anagram_simulated_heap and anagram_freeHeapPos. +- Renamed achPhrase and dictionary to anagram_achPhrase and + anagram_dictionary. +- Renamed CompareFrequency to anagram_CompareFrequency. +- Increased simulated heap in anagram_stdlib.c to 18000 bytes to + prevent segmentation fault. +- Changed header guard _WCCMALLOC_H to ANAGRAM_STRINGS_H. +- Renamed wccmalloc, wccbzero to anagram_malloc, anagram_bzero. +- Moved declaration of anagram_malloc to header anagram_stdlib.h. +- Introduced header guard ANAGRAM_CTYPE_H. +- Renamed wccislower, wccisupper, wccisalpha, wcctolower to + anagram_islower, anagram_isupper, anagram_isalpha, + anagram_tolower. +- Removed illegal keyword "inline". +- Changed header guard _WCCSTDLIB_H to ANAGRAM_STDLIB_H. +- Renamed wccqsort to anagram_qsort. +- Fixed compiler warning "no previous extern declaration for + non-static variable" for variables simulated_heap and + freeHeapPos by declaring them static. +- Renamed preprocessor define HEAP_SIZE to ANAGRAM_HEAP_SIZE. +- Fixed compiler warning "no previous prototype for function" by + moving includes to the top of the file. +- Fixed compiler warnings "implicit conversion changes signedness" + and "comparison of integers of different signs" by consistenly + using the type unsigned long in qsort helper functions. +- Moved function CompareFrequency to file anagram.c, added + declaration for it in file anagram_compare.h and included it in + anagram_stdlib.h. +- Fixed compiler warning "no previous extern declaration for + non-static variable" by adding forward declarations. +- Fixed compiler warning "macro is not used" by removing unused + macros MAXWORDS and i2ch. +- Replaced macro ch2i by proper function. +- Fixed compiler warning "array subscript is of type 'char' in + function CompareFrequency. +- Fixed compiler warning "unused variable" by removing variable i + in function Reset. +- Fixed compiler warning "no previous extern declaration for + non-static variable" by making global variables in file + anagram.c static. +- Replaced macro lPhrase by its expansion. +- Fixed compiler warnings "implicit conversion loses integer + precision" and "implicit conversion changes signedness" by + adding explicit casts or using the appropriate type for local + variables. +- Fixed compiler warning "array subscript is of type 'char'" by + changing type of some local variables as well as of global + variable achByFrequency to int. +- Changed all //-style comments to /* */-style comments. +- Moved contents of wccmalloc.c to anagram_stdlib.c. +- Renamed input.c to anagram_input.c. +- Renamed wccctype.h to anagram_ctype.h. +- Renamed wccstdlib.c to anagram_stdlib.c. +- Renamed wccstdlib.h to anagram_stdlib.h. +- Renamed wccmalloc.h to anagram_strings.h. +- Applied TACLeBench formatting rules via + astyle --options=doc/example/astylerc.txt +- Tested conformance to C99 via + clang -fsyntax-only -Weverything -Wno-unknown-pragmas -Wno-padded -pedantic -std=c99 + +2017-06-27 +- Remove static declarations. + +2017-07-10: +- Adjust alignment calculation in anagram_malloc to not add padding on already + aligned addresses. This prevents a buffer overflow of anagram_simulated_heap. diff --git a/baseline/source/anagram/anagram.c b/baseline/source/anagram/anagram.c new file mode 100644 index 0000000..8f140a3 --- /dev/null +++ b/baseline/source/anagram/anagram.c @@ -0,0 +1,670 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version 2.0 + + Name: anagram + + Author: Raymond Chen + + Function: A program that computes anagrams. + + Source: See below. + + Original name: anagram + + Changes: See ChangeLog.txt + + License: See below. + +*/ + +/* + Anagram program by Raymond Chen, + inspired by a similar program by Brian Scearce + + This program is Copyright 1991 by Raymond Chen. + (rjc@math.princeton.edu) + + This program may be freely distributed provided all alterations + to the original are clearly indicated as such. +*/ + +/* There are two tricks. First is the Basic Idea: + + When the user types in a phrase, the phrase is first preprocessed to + determine how many of each letter appears. A bit field is then constructed + dynamically, such that each field is large enough to hold the next power + of two larger than the number of times the character appears. For example, + if the phrase is hello, world, the bit field would be + + 00 00 00 000 000 00 00 + d e h l o r w + + The phrase hello, world, itself would be encoded as + + 01 01 01 011 010 01 01 + d e h l o r w + + and the word hollow would be encoded as + + 00 00 01 010 010 00 01 + d e h l o r w + + The top bit of each field is set in a special value called the sign. + Here, the sign would be + + 10 10 10 100 100 10 10 + d e h l o r w + + + The reason for packing the values into a bit field is that the operation + of subtracting out the letters of a word from the current phrase can be + carried out in parallel. for example, subtracting the word hello from + the phrase hello, world, is merely + + d e h l o r w + 01 01 01 011 010 01 01 (dehllloorw) + - 00 00 01 010 010 00 01 (hlloow) + ======================== + 01 01 00 001 000 01 00 (delr) + + Since none of the sign bits is set, the word fits, and we can continue. + Suppose the next word we tried was hood. + + d e h l o r w + 01 01 00 001 000 01 00 (delr) + - 01 00 01 000 010 00 00 (hood) + ======================== + 00 00 11 000 110 01 00 + ^ ^ + A sign bit is set. (Two, actually.) This means that hood does not + fit in delr, so we skip it and try another word. (Observe that + when a sign bit becomes set, it screws up the values for the letters to + the left of that bit, but that's not important.) + + The inner loop of an anagram program is testing to see if a + word fits in the collection of untried letters. Traditional methods + keep an array of 26 integers, which are then compared in turn. This + means that there are 26 comparisons per word. + + This method reduces the number of comparisons to MAX_QUAD, typically 2. + Instead of looping through an array, we merely perform the indicated + subtraction and test if any of the sign bits is set. +*/ + +/* The nuts and bolts: + + The dictionary is loaded and preprocessed. The preprocessed dictionary + is a concatenation of copies of the structure: + + struct dictword { + char bStructureSize; -- size of this structure + char cLetters; -- number of letters in the word + char achWord[]; -- the word itself (0-terminated) + } + + Since this is a variable-sized structure, we keep its size in the structure + itself for rapid stepping through the table. + + When a phrase is typed in, it is first preprocessed as described in the + Basic Idea. We then go through the dictionary, testing each word. If + the word fits in our phrase, we build the bit field for its frequency + table and add it to the list of candidates. +*/ + +/* + The Second Trick: + + Before diving into our anagram search, we then tabulate how many times + each letter appears in our list of candidates, and sort the table, with + the rarest letter first. + + We then do our anagram search. + + Like most anagram programs, this program does a depth-first search. + Although most anagram programs do some sort of heuristics to decide what + order to place words in the list_of_candidates, the search itself proceeds + according to a greedy algorithm. That is, once you find a word that fits, + subtract it and recurse. + + This anagram program exercises some restraint and does not march down + every branch that shows itself. Instead, it only goes down branches + that use the rarest unused letter. This helps to find dead ends faster. + + FindAnagram(unused_letters, list_of_candidates) { + l = the rarest letter as yet unused + For word in list_of_candidates { + if word does not fit in unused_letters, go on to the next word. + if word does not contain l, defer. + FindAnagram(unused_letters - word, list_of_candidates[word,...]) + } + } + + + The heuristic of the Second Trick can probably be improved. I invite + anyone willing to improve it to do so. +*/ + +/* Before compiling, make sure Quad and MASK_BITS are set properly. For best + results, make Quad the largest integer size supported on your machine. + So if your machine has long longs, make Quad an unsigned long long. + (I called it Quad because on most machines, the largest integer size + supported is a four-byte unsigned long.) + + If you need to be able to anagram larger phrases, increase MAX_QUADS. + If you increase it beyond 4, you'll have to add a few more loop unrolling + steps to FindAnagram. +*/ + +#include "../extra.h" +#include "anagram_ctype.h" +#include "anagram_stdlib.h" +#include "anagram_strings.h" + +#include "anagram_compare.h" + + +/* + Defines +*/ + +#define anagram_DICTWORDS 2279 +#define anagram_MASK_BITS 32 /* number of bits in a Quad */ +#define anagram_MAX_QUADS 2 /* controls largest phrase */ +#define anagram_MAXCAND 100 /* candidates */ +#define anagram_MAXSOL 51 /* words in the solution */ +#define anagram_ALPHABET 26 /* letters in the alphabet */ + +#define anagram_OneStep( i ) \ + if ( ( aqNext[ i ] = pqMask[ i ] - pw->aqMask[ i ] ) & anagram_aqMainSign[ i ] ) { \ + ppwStart ++; \ + continue; \ + } + + +/* + Type definitions +*/ + +typedef unsigned int anagram_Quad; /* for building our bit mask */ + +/* A Word remembers the information about a candidate word. */ +typedef struct { + char *pchWord; /* the word itself */ + anagram_Quad aqMask[ anagram_MAX_QUADS ]; /* the word's mask */ + unsigned cchLength; /* letters in the word */ + char padding[4]; +} anagram_Word; +typedef anagram_Word *anagram_PWord; +typedef anagram_Word **anagram_PPWord; + +/* A Letter remembers information about each letter in the phrase to + be anagrammed. */ +typedef struct { + unsigned uFrequency; /* how many times it appears */ + unsigned uShift; /* how to mask */ + unsigned uBits; /* the bit mask itself */ + unsigned iq; /* which Quad to inspect? */ +} anagram_Letter; +typedef anagram_Letter *anagram_PLetter; + + +/* + Forward declaration of functions +*/ + +void anagram_init( void ); +void anagram_main( void ); +int anagram_return( void ); +int anagram_ch2i( int ch ); +void anagram_AddWords( void ); +void anagram_BuildMask( char const *pchPhrase ); +void anagram_BuildWord( char *pchWord ); +void anagram_DumpWords( void ); +void anagram_FindAnagram( anagram_Quad *pqMask, + anagram_PPWord ppwStart, + int iLetter ); +anagram_PWord anagram_NewWord( void ); +anagram_PWord anagram_NextWord( void ); +void anagram_ReadDict( void ); +void anagram_Reset( void ); +void anagram_SortCandidates( void ); + + +/* + Declaration of global variables +*/ + +extern char const *anagram_achPhrase[ 3 ]; +extern char const *anagram_dictionary[ anagram_DICTWORDS ]; + +/* candidates we've found so far */ +static anagram_PWord anagram_apwCand[ anagram_MAXCAND ]; +/* how many of them? */ +static unsigned anagram_cpwCand; + +/* statistics on the current phrase */ +static anagram_Letter anagram_alPhrase[ anagram_ALPHABET ]; + +/* number of letters in phrase */ +static int anagram_cchPhraseLength; + +/* the bit field for the full phrase */ +static anagram_Quad anagram_aqMainMask[ anagram_MAX_QUADS ]; +/* where the sign bits are */ +static anagram_Quad anagram_aqMainSign[ anagram_MAX_QUADS ]; + +static const int anagram_cchMinLength = 3; + +/* auGlobalFrequency counts the number of times each letter appears, + summed over all candidate words. This is used to decide which letter + to attack first. */ +static unsigned anagram_auGlobalFrequency[ anagram_ALPHABET ]; +static int anagram_achByFrequency[ anagram_ALPHABET ]; /* for sorting */ + +/* the dictionary is read here */ +static char *anagram_pchDictionary; + +/* the answers */ +static anagram_PWord anagram_apwSol[ anagram_MAXSOL ]; +static int anagram_cpwLast; + +/* buffer to write an answer */ +static char anagram_buffer[30]; + +/* + Initialization- and return-value-related functions +*/ + +/* ReadDict -- read the dictionary file into memory and preprocess it + + A word of length cch in the dictionary is encoded as follows: + + byte 0 = cch + 3 + byte 1 = number of letters in the word + byte 2... = the word itself, null-terminated + + Observe that cch+3 is the length of the total encoding. These + byte streams are concatenated, and terminated with a 0. +*/ +void anagram_ReadDict( void ) +{ + char *pch; + char *pchBase; + unsigned len; + unsigned cWords = 0; + unsigned cLetters; + int i; + volatile char bitmask = 0; + + len = 0; + _Pragma( "loopbound min 2279 max 2279" ) + for ( i = 0; i < anagram_DICTWORDS; i ++ ) { + unsigned strlen = 0; + _Pragma( "loopbound min 1 max 5" ) + while ( anagram_dictionary[ i ][ strlen ] != 0 ) + strlen ++; + len += strlen + 2; + } + + pchBase = anagram_pchDictionary = ( char * )anagram_malloc( len ); + + _Pragma( "loopbound min 2279 max 2279" ) + for ( i = 0; i < anagram_DICTWORDS; i ++ ) { + int index = 0; + pch = pchBase + 2; /* reserve for length */ + cLetters = 0; + + _Pragma( "loopbound min 1 max 5" ) + while ( anagram_dictionary[ i ][ index ] != '\0' ) { + if ( anagram_isalpha( anagram_dictionary[ i ][ index ] ) ) + cLetters ++; + *pch ++ = anagram_dictionary[ i ][ index ]; + index ++; + *( pch - 1 ) ^= bitmask; + } + *pch ++ = '\0'; + *pchBase = ( char )( pch - pchBase ); + pchBase[ 1 ] = ( char )cLetters; + pchBase = pch; + cWords ++; + } + + *pchBase ++ = 0; +} + + +void anagram_init( void ) +{ + anagram_ReadDict(); +} + + +int anagram_return( void ) +{ + int i; + char const *answer = "duke rip amy"; + + for ( i = 0; i < 12; i++ ) + if ( answer[ i ] != anagram_buffer[ i ] ) + return 1; + + return 0; +} + + +/* + Core benchmark functions +*/ + +/* convert letter to index */ +int anagram_ch2i( int ch ) +{ + return ch - 'a'; +} + + +int anagram_CompareFrequency( char *pch1, char *pch2 ) +{ + return anagram_auGlobalFrequency[ ( (int) *pch1 ) ] < + anagram_auGlobalFrequency[ ( (int) *pch2 ) ] + ? -1 : + anagram_auGlobalFrequency[ ( (int) *pch1 ) ] == + anagram_auGlobalFrequency[ ( (int) *pch2 ) ] + ? 0 : 1; +} + + +void anagram_Reset( void ) +{ + anagram_bzero( ( char * )anagram_alPhrase, + sizeof( anagram_Letter ) * anagram_ALPHABET ); + anagram_bzero( ( char * )anagram_aqMainMask, + sizeof( anagram_Quad ) * anagram_MAX_QUADS ); + anagram_bzero( ( char * )anagram_aqMainSign, + sizeof( anagram_Quad ) * anagram_MAX_QUADS ); + anagram_bzero( ( char * )anagram_auGlobalFrequency, + sizeof( unsigned ) * anagram_ALPHABET ); + anagram_bzero( ( char * )anagram_achByFrequency, + sizeof( int ) * anagram_ALPHABET ); + anagram_bzero( ( char * )anagram_apwCand, + sizeof( anagram_PWord ) * anagram_MAXCAND ); + anagram_cchPhraseLength = 0; + anagram_cpwCand = 0; +} + + +void anagram_BuildMask( char const *pchPhrase ) +{ + int i; + int ch; + unsigned iq; /* which Quad? */ + unsigned int cbtUsed; /* bits used in the current Quad */ + unsigned int cbtNeed; /* bits needed for current letter */ + anagram_Quad qNeed; /* used to build the mask */ + + /* Tabulate letter frequencies in the phrase */ + anagram_cchPhraseLength = 0; + _Pragma( "loopbound min 11 max 12" ) + while ( ( ch = *pchPhrase ++ ) != '\0' ) { + if ( anagram_isalpha( ch ) ) { + ch = anagram_tolower( ch ); + anagram_alPhrase[ anagram_ch2i( ch ) ].uFrequency ++; + anagram_cchPhraseLength ++; + } + } + + /* Build masks */ + iq = 0; /* which quad being used */ + cbtUsed = 0; /* bits used so far */ + + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) { + if ( anagram_alPhrase[ i ].uFrequency == 0 ) { + anagram_auGlobalFrequency[ i ] = ~0u; /* to make it sort last */ + } else { + anagram_auGlobalFrequency[ i ] = 0u; + _Pragma( "loopbound min 1 max 2" ) + for ( cbtNeed = 1, qNeed = 1; + anagram_alPhrase[ i ].uFrequency >= qNeed; + cbtNeed ++, qNeed <<= 1 ) + ; + if ( cbtUsed + cbtNeed > anagram_MASK_BITS ) + cbtUsed = 0; + anagram_alPhrase[ i ].uBits = qNeed - 1; + if ( cbtUsed ) + qNeed <<= cbtUsed; + anagram_aqMainSign[ iq ] |= qNeed; + anagram_aqMainMask[ iq ] |= + ( anagram_Quad )anagram_alPhrase[ i ].uFrequency << cbtUsed; + anagram_alPhrase[ i ].uShift = cbtUsed; + anagram_alPhrase[ i ].iq = iq; + cbtUsed += cbtNeed; + } + } +} + + +anagram_PWord anagram_NewWord( void ) +{ + anagram_PWord pw; + + pw = ( anagram_Word * )anagram_malloc( sizeof( anagram_Word ) ); + return pw; +} + + +/* NextWord -- get another candidate entry, creating if necessary */ +anagram_PWord anagram_NextWord( void ) +{ + anagram_PWord pw; + pw = anagram_apwCand[ anagram_cpwCand ++ ]; + if ( pw != 0 ) + return pw; + anagram_apwCand[ anagram_cpwCand - 1 ] = anagram_NewWord(); + return anagram_apwCand[ anagram_cpwCand - 1 ]; +} + + +/* BuildWord -- build a Word structure from an ASCII word + If the word does not fit, then do nothing. */ +void anagram_BuildWord( char *pchWord ) +{ + unsigned char cchFrequency[ anagram_ALPHABET ]; + int i; + char *pch = pchWord; + anagram_PWord pw; + unsigned int cchLength = 0; + + anagram_bzero( ( char * )cchFrequency, + sizeof( unsigned char ) * anagram_ALPHABET ); + + /* Build frequency table */ + _Pragma( "loopbound min 3 max 636" ) + while ( ( i = *pch ++ ) != '\0' ) { + if ( !anagram_isalpha( i ) ) + continue; + i = anagram_ch2i( anagram_tolower( i ) ); + if ( ++ cchFrequency[ i ] > anagram_alPhrase[ i ].uFrequency ) + return ; + ++ cchLength; + } + + /* Update global count */ + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) + anagram_auGlobalFrequency[ i ] += cchFrequency[ i ]; + + /* Create a Word structure and fill it in, including building the + bitfield of frequencies. */ + pw = anagram_NextWord(); + anagram_bzero( ( char * )( pw->aqMask ), + sizeof( anagram_Quad ) * anagram_MAX_QUADS ); + + pw->pchWord = pchWord; + pw->cchLength = cchLength; + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) { + pw->aqMask[ anagram_alPhrase[i].iq ] |= + ( anagram_Quad )cchFrequency[ i ] << anagram_alPhrase[ i ].uShift; + } +} + + +/* AddWords -- build the list of candidates */ +void anagram_AddWords( void ) +{ + char *pch = anagram_pchDictionary; /* walk through the dictionary */ + + anagram_cpwCand = 0; + + _Pragma( "loopbound min 1967 max 1967" ) + while ( *pch ) { + if ( ( pch[ 1 ] >= anagram_cchMinLength && + pch[ 1 ] + anagram_cchMinLength <= anagram_cchPhraseLength ) + || pch[ 1 ] == anagram_cchPhraseLength ) + anagram_BuildWord( pch + 2 ); + pch += *pch; + } +} + + +void anagram_DumpWords( void ) +{ + int i, j; + int offset = 0; + _Pragma( "loopbound min 3 max 3" ) + for ( i = 0; i < anagram_cpwLast; i ++ ) { + _Pragma( "loopbound min 3 max 5" ) + for ( j = 0; anagram_apwSol[ i ]->pchWord[ j ] != '\0'; j ++ ) + anagram_buffer[ offset + j ] = anagram_apwSol[ i ]->pchWord[ j ]; + offset += j; + + anagram_buffer[ offset ++ ] = ' '; + } + anagram_buffer[ offset ++ ] = '\0'; +} + + +void anagram_FindAnagram( anagram_Quad *pqMask, anagram_PPWord ppwStart, + int iLetter ) +{ + anagram_Quad aqNext[ anagram_MAX_QUADS ]; + register anagram_PWord pw; + anagram_Quad qMask; + unsigned iq; + anagram_PPWord ppwEnd = &anagram_apwCand[ 0 ]; + ppwEnd += anagram_cpwCand; + + _Pragma( "loopbound min 1 max 7" ) + while ( 1 ) { + iq = anagram_alPhrase[ anagram_achByFrequency[iLetter] ].iq; + qMask = anagram_alPhrase[ anagram_achByFrequency[iLetter] ].uBits << + anagram_alPhrase[ anagram_achByFrequency[iLetter] ].uShift; + if ( pqMask[ iq ] & qMask ) + break; + iLetter ++; + } + + _Pragma( "loopbound min 0 max 114" ) + while ( ppwStart < ppwEnd ) { + pw = *ppwStart; + + #if anagram_MAX_QUADS > 0 + anagram_OneStep( 0 ); + #endif + + #if anagram_MAX_QUADS > 1 + anagram_OneStep( 1 ); + #endif + + #if anagram_MAX_QUADS > 2 + anagram_OneStep( 2 ); + #endif + + #if anagram_MAX_QUADS > 3 + anagram_OneStep( 3 ); + #endif + + #if anagram_MAX_QUADS > 4 + @@"Add more unrolling steps here, please."@@ + #endif + + /* If the pivot letter isn't present, defer this word until later */ + if ( ( pw->aqMask[ iq ] & qMask ) == 0 ) { + *ppwStart = *( -- ppwEnd ); + *ppwEnd = pw; + continue; + } + + /* If we get here, this means the word fits. */ + anagram_apwSol[ anagram_cpwLast ++ ] = pw; + if ( anagram_cchPhraseLength -= pw->cchLength ) { /* recurse */ + /* The recursive call scrambles the tail, so we have to be + pessimistic. */ + ppwEnd = &anagram_apwCand[ 0 ]; + ppwEnd += anagram_cpwCand; + anagram_FindAnagram( &aqNext[ 0 ], ppwStart, iLetter ); + } else { /* found one */ + anagram_DumpWords(); + } + anagram_cchPhraseLength += pw->cchLength; + -- anagram_cpwLast; + ppwStart ++; + continue; + } +} + + +void anagram_SortCandidates( void ) +{ + int i; + + /* Sort the letters by frequency */ + _Pragma( "loopbound min 26 max 26" ) + for ( i = 0; i < anagram_ALPHABET; i ++ ) + anagram_achByFrequency[ i ] = i; + anagram_qsort( anagram_achByFrequency, anagram_ALPHABET, sizeof( int ) ); +} + + +void _Pragma( "entrypoint" ) anagram_main( void ) +{ + int i; + + _Pragma( "loopbound min 3 max 3" ) + for ( i = 0; i < 3; i ++ ) { + anagram_Reset(); + anagram_BuildMask( anagram_achPhrase[ i ] ); + anagram_AddWords(); + if ( anagram_cpwCand == 0 || anagram_cchPhraseLength == 0 ) + continue; + + anagram_cpwLast = 0; + anagram_SortCandidates(); + _Pragma( "marker call_find" ) + anagram_FindAnagram( anagram_aqMainMask, anagram_apwCand, 0 ); + _Pragma( "flowrestriction 1*anagram_FindAnagram <= 51*call_find" ) + } +} + + +/* + Main function +*/ + +int main(int argc, char **argv) +{ + SET_UP + //int jobsComplete; + //int maxJobs=100; + //for(jobsComplete=-1; jobsComplete 1 ) { + if ( n > 10 ) + pi = anagram_pivot( a, n, es ); + else + pi = a + ( n >> 1 ) * es; + + anagram_swapi( a, pi, es ); + pi = a; + pn = a + n * es; + pj = pn; + _Pragma( "loopbound min 1 max 11" ) + while ( 1 ) { + /* wcc note: this assignment expression was added to avoid assignment of + multiple loop bound annotations to same loop (cf. Ticket #0002323). */ + flowfactdummy ++; + _Pragma( "loopbound min 1 max 5" ) + do { + pi += es; + } while ( pi < pn && anagram_CompareFrequency( pi, a ) < 0 ); + _Pragma( "loopbound min 1 max 4" ) + do { + pj -= es; + } while ( pj > a && anagram_CompareFrequency( pj, a ) > 0 ); + if ( pj < pi ) + break; + anagram_swapi( pi, pj, es ); + } + anagram_swapi( a, pj, es ); + j = ( unsigned long )( pj - a ) / es; + + n = n - j - 1; + if ( j >= n ) { + anagram_qsorts( a, j, es ); + a += ( j + 1 ) * es; + } else { + anagram_qsorts( a + ( j + 1 )*es, n, es ); + n = j; + } + } +} + +void anagram_qsort( void *va, unsigned long n, unsigned long es ) +{ + _Pragma( "marker call_qsorts" ) + anagram_qsorts( ( char * )va, n, es ); + _Pragma( "flowrestriction 1*anagram_qsorts <= 17*call_qsorts" ) +} + + +/* This must be redefined for each new benchmark */ +#define ANAGRAM_HEAP_SIZE 18000 + +static char anagram_simulated_heap[ANAGRAM_HEAP_SIZE]; +static unsigned int anagram_freeHeapPos; + +void *anagram_malloc( unsigned int numberOfBytes ) +{ + void *currentPos = ( void * )&anagram_simulated_heap[ anagram_freeHeapPos ]; + /* Get a 4-byte address for alignment purposes */ + //anagram_freeHeapPos += ( ( numberOfBytes + 4 ) & ( unsigned int )0xfffffffc ); + unsigned int rem = (numberOfBytes & ( unsigned int )0x3 ); + unsigned int adjustment = rem ? 4 - rem : 0; + anagram_freeHeapPos += numberOfBytes + adjustment; + return currentPos; +} + +void anagram_bzero( char *p, unsigned long len ) +{ + unsigned long i; + + _Pragma( "loopbound min 8 max 416" ) + for ( i = 0; i < len; ++ i ) + *p ++ = '\0'; +} + diff --git a/baseline/source/anagram/anagram_stdlib.h b/baseline/source/anagram/anagram_stdlib.h new file mode 100644 index 0000000..0e745d5 --- /dev/null +++ b/baseline/source/anagram/anagram_stdlib.h @@ -0,0 +1,29 @@ +/* + + This header is part of the TACLeBench benchmark suite. + Version 2.0 + + Name: anagram_stdlib.h + + Author: Raymond Chen + + Function: This header contains some C standard library functions used by anagram. + + Source: unknown + + Original name: anagram + + Changes: See ChangeLog.txt + + License: See anagram.c + +*/ + +#ifndef ANAGRAM_STDLIB_H +#define ANAGRAM_STDLIB_H + +void *anagram_malloc( unsigned int numberOfBytes ); + +void anagram_qsort( void *va, unsigned long n, unsigned long es ); + +#endif diff --git a/baseline/source/anagram/anagram_strings.h b/baseline/source/anagram/anagram_strings.h new file mode 100644 index 0000000..1e023fc --- /dev/null +++ b/baseline/source/anagram/anagram_strings.h @@ -0,0 +1,27 @@ +/* + + This header is part of the TACLeBench benchmark suite. + Version 2.0 + + Name: anagram_strings.h + + Author: Raymond Chen + + Function: This header contains some C standard library functions used by anagram. + + Source: unknown + + Original name: anagram + + Changes: See ChangeLog.txt + + License: See anagram.c + +*/ + +#ifndef ANAGRAM_STRINGS_H +#define ANAGRAM_STRINGS_H + +void anagram_bzero( char *p, unsigned long len ); + +#endif diff --git a/baseline/source/audiobeam/README b/baseline/source/audiobeam/README new file mode 100644 index 0000000..e228eda --- /dev/null +++ b/baseline/source/audiobeam/README @@ -0,0 +1,86 @@ +Readme file for Oxygen beamforming source code distribution +----------------------------------------------------------- + +This is a very very beta distribution of beamforming source code from +MIT LCS. + +There is only one source file, main.c, and one header file, +main.h. You can compile everything using the Makefile included in the +distribution. + +The input to the program is a text file containing floating +point values for the signal read on each of the microphones. For n +microphones, each line of the text files represents a temporal sample +and should contain n floating point values separated by spaces, e.g.: + +-1.8569790e-004 -9.0919049e-004 3.6711283e-004 -1.0073081e-005 ... + +There are several modes of operation for the program: + +1. The most basic mode is to process the microphone data and to +calculate the output based on one beam focused on a particular point +in space. The coordinates for the microphones and the focus point are +specified inside main.c (eventually to be moved to a separate file). + +2. Far field search mode. This mode assumes a far-field source (which +means we have a planar wavefront) and a linear array, and sweeps over +180 degrees in the plane of the array. The microphone coordinates are +specified in main.c, and the NUM_ANGLES constant defines how many +angle values should be tested (a value of 180 means one beam per each +degree). The energy of the signal over a particular window +(ANGLE_ENERGY_WINDOW_SIZE) is computed for each beam. The direction +with maximum energy is considered the direction that the speech signal +is coming from, and is printed out by the program. + +3. Near-field hill climbing mode. This mode accepts a starting +coordinate and attempts to "hill-climb" through the space seeking the +maximum energy. Each of the x, y, and z coordinates are perturbed in +the positive and negative directions at each time interval +(GRID_ENERGY_WINDOW_SIZE) by a step size (GRID_STEP_SIZE). This +perturbation, along with the original coordinate, produces seven +coordinates to be tested. The direction with the maximum energy +replaces the current reference coordinate. For instance, if we have a +starting reference coordinate of (1,1,0) and our step size is 0.01, we +will evaluate the energy for the following seven beams: + +(1,1,0) +(0.99,1,0) +(1.01,1,0) +(1,0.99,0) +(1,1.01,0) +(1,1,-0.01) +(1,1,0.01) + +Now let's say the beam (1,1.01,0) has the maximum energy; then this +coordinate will replace the original reference coordinate of (1,1,0). + +For methods 2, and 3, we are not outputting anything to disk, we are +just printing the result. This is because we have just started to work +with these methods, and have not applied them in real systems. This +code is currently being ported to RAW. + +To get a list of parameters for the delay_and_sum executable that is +generated when the source is compiled, just type ./delay_and_sum . + +There is some sample data included with the program, in the data +directory. There is some data for a near-field and far-field +source. The README.txt file in each directory specifies the microphone +and source position. The data1 file, when processed with a beamformer +aligned in the proper direction should produce something like a sinc +function (see +http://ccrma-www.stanford.edu/~jos/Interpolation/sinc_function.html). + +The data2 file should produce an audio signal of a woman saying "the +simplest method". If the beamformer is aligned properly, the noise +should be reduced significantly over the source signal from only one +of the microphones (use print_datafile.pl to isolate one +microphone). You can convert the data file that the program produces +to wave files using sox. + + + + + +--------------------------------- +Eugene Weinstein +ecoder@mit.edu \ No newline at end of file diff --git a/baseline/source/audiobeam/audiobeam.c b/baseline/source/audiobeam/audiobeam.c new file mode 100644 index 0000000..ed5d656 --- /dev/null +++ b/baseline/source/audiobeam/audiobeam.c @@ -0,0 +1,594 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: audiobeam + + Author: Eugene Weinstein + + Function: Audio beam former + + Source: StreamIt + http://groups.csail.mit.edu/cag/streamit/ + + Changes: no functional changes + + License: see license.txt + +*/ + + +/* + Include section +*/ + +#include "../extra.h" +#include "audiobeamlibm.h" +#include "audiobeamlibmalloc.h" +#include "audiobeam.h" + +/* + Forward declaration of functions +*/ + +void audiobeam_init(); +int audiobeam_return(); +void audiobeam_main( void ); +//int main( void ); +void audiobeam_preprocess_delays( struct audiobeam_PreprocessedDelays + prep_delays[], float *delays ); +float *audiobeam_parse_line( float *float_arr, int num_mic ); +long int audiobeam_find_max_in_arr( float *arr, int size ); +long int audiobeam_find_min_in_arr( float *arr, int size ); +int audiobeam_wrapped_inc_offset( int i, int offset, int max_i ); +int audiobeam_wrapped_dec_offset( int i, int offset, int max_i ); +int audiobeam_wrapped_inc( int i, int max_i ); +int audiobeam_wrapped_dec( int i, int max_i ); +struct audiobeam_DataQueue *audiobeam_init_data_queue( int max_delay, + int num_mic ); +struct audiobeam_Delays *audiobeam_init_delays ( int num_angles, int num_mic ); +void audiobeam_calc_distances( float *source_location, + float audiobeam_mic_locations[15][3], + float *distances, + int num_mic ); +void audiobeam_calc_delays( float *distances, float *delays, int sound_speed, + int sampling_rate, int num_mic ); +void audiobeam_adjust_delays( float *delays, int num_mic ); +float *audiobeam_calc_weights_lr ( int num_mic ); +float *audiobeam_calc_weights_left_only ( int num_mic ); +float audiobeam_calculate_energy( float *samples, int num_samples ); +float audiobeam_do_beamforming( struct audiobeam_PreprocessedDelays + preprocessed_delays[], + float **sample_queue, + int queue_head, + long int max_delay, + int num_mic, + float *weights ); +int audiobeam_process_signal( struct audiobeam_Delays *delays, int num_mic, + float sampling_rate, float **beamform_results, + struct audiobeam_DataQueue *queue, + int num_beams, int window, float *weights ); +int audiobeam_calc_beamforming_result( struct audiobeam_Delays *delays, + float **beamform_results, + float *energies, + struct audiobeam_DataQueue *queue, + int num_beams, int window, + int hamming ); +void audiobeam_calc_single_pos( float source_location[3], + float audiobeam_mic_locations[15][3], + int hamming ); + + +/* + Declaration of global variables +*/ + +extern float audiobeam_input[5760]; +extern float audiobeam_mic_locations[15][3]; +extern float audiobeam_source_location[3]; +extern float audiobeam_origin_location[3]; +int audiobeam_input_pos; +int audiobeam_checksum; + + +/* + Initialization- and return-value-related functions +*/ + +void audiobeam_init() +{ + audiobeam_input_pos = 0; + audiobeam_checksum = 0; + + unsigned int i; + unsigned char *p; + volatile char bitmask = 0; + + /* + Apply volatile XOR-bitmask to entire input array. + */ + p = ( unsigned char * ) &audiobeam_input[ 0 ]; + _Pragma( "loopbound min 23040 max 23040" ) + for ( i = 0; i < sizeof( audiobeam_input ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &audiobeam_mic_locations[ 0 ]; + _Pragma( "loopbound min 180 max 180" ) + for ( i = 0; i < sizeof( audiobeam_mic_locations ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &audiobeam_source_location[ 0 ]; + _Pragma( "loopbound min 12 max 12" ) + for ( i = 0; i < sizeof( audiobeam_source_location ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &audiobeam_origin_location[ 0 ]; + _Pragma( "loopbound min 12 max 12" ) + for ( i = 0; i < sizeof( audiobeam_origin_location ); ++i, ++p ) + *p ^= bitmask; +} + + +int audiobeam_return() +{ + return ( audiobeam_checksum +1!= 0 ); +} + + +/* + Algorithm core functions +*/ + +void audiobeam_preprocess_delays( struct audiobeam_PreprocessedDelays + prep_delays[], float *delays ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < 15; i++ ) { + prep_delays[i].delay = delays[i]; + prep_delays[i].high = ( int ) audiobeam_ceil( delays[i] ); + prep_delays[i].low = ( int ) audiobeam_floor( delays[i] ); + prep_delays[i].offset = delays[i] - prep_delays[i].low; + } +} + + +float *audiobeam_parse_line( float *float_arr, int num_mic ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) + float_arr[i] = audiobeam_input[audiobeam_input_pos++]; + + return float_arr; +} + + +long int audiobeam_find_max_in_arr( float *arr, int size ) +{ + int i; + float max = 0; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < size; i++ ) { + if ( arr[i] > max ) + max = arr[i]; + } + + return audiobeam_ceil( max ); +} + + +long int audiobeam_find_min_in_arr( float *arr, int size ) +{ + int i; + float min = arr[0]; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < size; i++ ) { + if ( arr[i] < min ) + min = arr[i]; + } + + return audiobeam_floor( min ); +} + + +int audiobeam_wrapped_inc_offset( int i, int offset, int max_i ) +{ + if ( i + offset > max_i ) + return ( i + offset - max_i - 1 ); + else + return ( i + offset ); +} + + +int audiobeam_wrapped_dec_offset( int i, int offset, int max_i ) +{ + if ( i - offset < 0 ) + return ( max_i - ( offset - i ) + 1 ); + else + return ( i - offset ); +} + + +int audiobeam_wrapped_inc( int i, int max_i ) +{ + return audiobeam_wrapped_inc_offset( i, 1, max_i ); +} + + +int audiobeam_wrapped_dec( int i, int max_i ) +{ + return audiobeam_wrapped_dec_offset( i, 1, max_i ); +} + + +struct audiobeam_DataQueue *audiobeam_init_data_queue( int max_delay, + int num_mic ) +{ + int i, j; + + struct audiobeam_DataQueue *queue; + queue = ( struct audiobeam_DataQueue * ) audiobeam_malloc( sizeof( + struct audiobeam_DataQueue ) ); + queue->sample_queue = ( float ** ) audiobeam_malloc( ( max_delay + 1 ) + * sizeof( float * ) ); + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < ( max_delay + 1 ); i++ ) { + ( queue->sample_queue )[i] = ( float * ) audiobeam_malloc( num_mic + * sizeof( float ) ); + _Pragma( "loopbound min 15 max 15" ) + for ( j = 0; j < num_mic; j++ ) { + ( queue->sample_queue )[i][j] = 0.0; // Initialize values to 0 + } + } + + queue->head = 0; + queue->tail = 0; + queue->full = 0; + + return queue; +} + + +struct audiobeam_Delays *audiobeam_init_delays ( int num_angles, int num_mic ) +{ + struct audiobeam_Delays *delays; + int i; + + delays = ( struct audiobeam_Delays * ) audiobeam_malloc( sizeof( + struct audiobeam_Delays ) ); + + // Initialize the delays array + delays->delay_values = ( float ** ) audiobeam_malloc( num_angles + * sizeof( float * ) ); + + _Pragma( "loopbound min 1 max 1" ) + for ( i = 0; i < ( num_angles ); i++ ) { + delays->delay_values[i] = ( float * ) audiobeam_malloc( num_mic + * sizeof( float ) ); + } + + return delays; +} + +void audiobeam_calc_distances( float *source_location, + float audiobeam_mic_locations[15][3], + float *distances, + int num_mic ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) { + distances[i] = ( audiobeam_sqrt( ( audiobeam_mic_locations[i][0] + - source_location[0] ) * + ( audiobeam_mic_locations[i][0] + - source_location[0] ) + + ( audiobeam_mic_locations[i][1] + - source_location[1] ) * + ( audiobeam_mic_locations[i][1] + - source_location[1] ) + + ( audiobeam_mic_locations[i][2] + - source_location[2] ) * + ( audiobeam_mic_locations[i][2] + - source_location[2] ) ) ); + } +} + + +void audiobeam_calc_delays( float *distances, float *delays, int sound_speed, + int sampling_rate, int num_mic ) +{ + int i; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) + delays[i] = ( distances[i] / sound_speed ) * sampling_rate; +} + + +void audiobeam_adjust_delays( float *delays, int num_mic ) +{ + int i; + long int min_delay = audiobeam_find_min_in_arr ( delays, num_mic ) - 1; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) + delays[i] -= min_delay; +} + + +float *audiobeam_calc_weights_lr ( int num_mic ) +{ + float *weights = ( float * ) audiobeam_malloc( num_mic * sizeof( float ) ); + int index = 0; + int y, z; + + int half = num_mic / 4; + + _Pragma( "loopbound min 0 max 0" ) + for ( z = 1; z >= -1; z -= 2 ) { + _Pragma( "loopbound min 0 max 0" ) + for ( y = 0; y < half; y++ ) { + weights[index] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * y + / half ); + index++; + } + _Pragma( "loopbound min 0 max 0" ) + for ( y = 0; y < half; y++ ) { + weights[index] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * ( -y ) + / half ); + index++; + } + } + + return weights; +} + + +float *audiobeam_calc_weights_left_only ( int num_mic ) +{ + float *weights = ( float * ) audiobeam_malloc( num_mic * sizeof( float ) ); + int index = 0; + int y; + + int half = num_mic / 2; + + _Pragma( "loopbound min 15 max 15" ) + for ( y = -half; y <= half; y++ ) { + weights[index] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * y / half ); + index++; + } + + return weights; +} + + +float audiobeam_calculate_energy( float *samples, int num_samples ) +{ + int i; + float sum = 0.0; + + _Pragma( "loopbound min 0 max 0" ) + for ( i = 0; i < num_samples; i++ ) + sum += ( samples[i] * samples[i] ); + + return sum; +} + + +float audiobeam_do_beamforming( struct audiobeam_PreprocessedDelays + preprocessed_delays[], + float **sample_queue, + int queue_head, + long int max_delay, + int num_mic, + float *weights ) +{ + int i; + float sum = 0; + int delay_floor; + int delay_ceil; + int low_index; + int high_index; + float interpolated_value; + + // add up all the num_mic delayed samples + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < num_mic; i++ ) { + delay_floor = preprocessed_delays[i].low; + delay_ceil = preprocessed_delays[i].high; + + // Inline wrap around here + // Low index gets index of sample right before desired sample + low_index = queue_head + delay_floor; + if ( low_index > max_delay ) + low_index -= ( max_delay + 1 ); + + // High index gets index of sample right after desired sample + high_index = queue_head + delay_ceil; + if ( high_index > max_delay ) + high_index -= ( max_delay + 1 ); + + // i gives the value of the microphone we want. However, since + // the array only has microphones first_mic to last_mic, we + // need to offset our index by first_mic + + interpolated_value = ( ( ( sample_queue[high_index][i] - + sample_queue[low_index][i] ) + * ( preprocessed_delays[i].offset ) ) + + sample_queue[low_index][i] ); + + // If we have microphone weights, multiply the value by the weight + if ( weights != 0 ) + sum += ( interpolated_value * weights[i] ); + else + sum += interpolated_value; + } + + return sum; + +} + + +int audiobeam_process_signal( struct audiobeam_Delays *delays, int num_mic, + float sampling_rate, float **beamform_results, + struct audiobeam_DataQueue *queue, + int num_beams, int window, float *weights ) +{ + int i, j; + float time_index = 0; + float time_index_inc = ( 1.0 / sampling_rate ); + + float value; + + int done = 0; + + struct audiobeam_PreprocessedDelays preprocessed_delays[15]; + + audiobeam_preprocess_delays( preprocessed_delays, delays->delay_values[0] ); + + _Pragma( "loopbound min 13 max 13" ) + for ( i = 0; i < delays->max_delay - 1; i++ ) { + if ( audiobeam_input_pos < 5760 ) + audiobeam_parse_line( ( queue->sample_queue )[queue->head], 15 ); + else + return -1; + queue->head = audiobeam_wrapped_inc( queue->head, delays->max_delay ); + } + _Pragma( "loopbound min 371 max 371" ) + for ( i = 0; ( i < window ) || ( window < 0 ) ; i++ ) { + if ( audiobeam_input_pos < 5760 ) + audiobeam_parse_line( ( queue->sample_queue )[queue->head], 15 ); + else { + done = 1; + break; + } + + _Pragma( "loopbound min 1 max 1" ) + for ( j = 0; j < num_beams; j++ ) { + value = audiobeam_do_beamforming( preprocessed_delays, + ( queue->sample_queue ), + audiobeam_wrapped_inc( queue->head, + delays->max_delay ), + delays->max_delay, num_mic, weights ); + + + value = value / num_mic; + + if ( beamform_results != 0 ) + beamform_results[j][i] = value; + } + + queue->tail = queue->head; + queue->head = audiobeam_wrapped_inc( queue->head, delays->max_delay ); + + time_index += time_index_inc; + } + + return ( done ); +} + + +int audiobeam_calc_beamforming_result( struct audiobeam_Delays *delays, + float **beamform_results, + float *energies, + struct audiobeam_DataQueue *queue, + int num_beams, int window, + int hamming ) +{ + int i; + int done; + float *weights = 0; + + if ( hamming ) { + if ( ( 15 % 2 ) == 1 ) + weights = audiobeam_calc_weights_left_only( 15 ); + else + weights = audiobeam_calc_weights_lr( 15 ); + } + + done = audiobeam_process_signal( delays, 15, 16000, + beamform_results, + queue, num_beams, window, weights ); + + if ( beamform_results != 0 ) { + _Pragma( "loopbound min 1 max 1" ) + for ( i = 0; i < num_beams; i++ ) + energies[i] = audiobeam_calculate_energy( beamform_results[i], window ); + } + return done; +} + + +void audiobeam_calc_single_pos( float source_location[3], + float audiobeam_mic_locations[15][3], + int hamming ) +{ + float mic_distances[15]; + struct audiobeam_Delays *delays = audiobeam_init_delays( 1, 15 ); + struct audiobeam_DataQueue *queue; + + float **beamform_results; + float *energies; + + beamform_results = ( float ** ) audiobeam_malloc( 1 * sizeof( float * ) ); + beamform_results[0] = ( float * ) audiobeam_malloc( 384 * sizeof( float ) ); + energies = ( float * ) audiobeam_malloc( 1 * sizeof( float * ) ); + + // Calculate distances from source to each of mics + audiobeam_calc_distances( source_location, audiobeam_mic_locations, + mic_distances, 15 ); + + audiobeam_calc_delays( mic_distances, + delays->delay_values[0], + 342, 16000, 15 ); + + audiobeam_adjust_delays( delays->delay_values[0], 15 ); + + delays->max_delay = audiobeam_find_max_in_arr ( delays->delay_values[0], 15 ); + + queue = audiobeam_init_data_queue( delays->max_delay, 15 ); + + audiobeam_calc_beamforming_result( delays, beamform_results, + energies, queue, 1, -1, hamming ); + + audiobeam_checksum += beamform_results[0][0] * 1000; +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) audiobeam_main( void ) +{ + char hamming = 1; + audiobeam_calc_single_pos( audiobeam_source_location, + audiobeam_mic_locations, + hamming ); +} + + +int main( int argc, char **argv ) +{ + //SET_UP + int jobsComplete; + int maxJobs=100; + for (jobsComplete=-1; jobsComplete 0 ) { + z = x - audiobeam_pio2_1; + if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { + y[0] = z - audiobeam_pio2_1t; + y[1] = ( z - y[0] ) - audiobeam_pio2_1t; + } else { + z -= audiobeam_pio2_2; + y[0] = z - audiobeam_pio2_2t; + y[1] = ( z - y[0] ) - audiobeam_pio2_2t; + } + return 1; + } else { + z = x + audiobeam_pio2_1; + if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { + y[0] = z + audiobeam_pio2_1t; + y[1] = ( z - y[0] ) + audiobeam_pio2_1t; + } else { + z += audiobeam_pio2_2; + y[0] = z + audiobeam_pio2_2t; + y[1] = ( z - y[0] ) + audiobeam_pio2_2t; + } + return -1; + } + } + if ( ix <= 0x43490f80 ) { + t = audiobeam_fabsf( x ); + n = ( int ) ( t * audiobeam_invpio2 + audiobeam_half ); + fn = ( float )n; + r = t - fn * audiobeam_pio2_1; + w = fn * audiobeam_pio2_1t; + if ( n < 32 && ( int )( ix & 0xffffff00 ) != audiobeam_npio2_hw[n - 1] ) + y[0] = r - w; + else { + unsigned int high; + j = ix >> 23; + y[0] = r - w; + AUDIOBEAM_GET_FLOAT_WORD( high, y[0] ); + i = j - ( ( high >> 23 ) & 0xff ); + if ( i > 8 ) { + t = r; + w = fn * audiobeam_pio2_2; + r = t - w; + w = fn * audiobeam_pio2_2t - ( ( t - r ) - w ); + y[0] = r - w; + AUDIOBEAM_GET_FLOAT_WORD( high, y[0] ); + i = j - ( ( high >> 23 ) & 0xff ); + if ( i > 25 ) { + t = r; + w = fn * audiobeam_pio2_3; + r = t - w; + w = fn * audiobeam_pio2_3t - ( ( t - r ) - w ); + y[0] = r - w; + } + } + } + y[1] = ( r - y[0] ) - w; + if ( hx < 0 ) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } else return n; + } + if ( ix >= 0x7f800000 ) { + y[0] = y[1] = x - x; + return 0; + } + + return n; +} + + +float audiobeam___kernel_cosf( float x, float y ) +{ + float a, hz, z, r, qx; + int ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + ix &= 0x7fffffff; + if ( ix < 0x32000000 ) { + if ( ( ( int )x ) == 0 ) return audiobeam_one; + } + z = x * x; + r = z * ( audiobeam_C1 + z * ( audiobeam_C2 + z * ( audiobeam_C3 + z * + ( audiobeam_C4 + z * + ( audiobeam_C5 + z * audiobeam_C6 ) ) ) ) ); + if ( ix < 0x3e99999a ) + return audiobeam_one - ( ( float )0.5f * z - ( z * r - x * y ) ); + else { + if ( ix > 0x3f480000 ) + qx = ( float )0.28125f; + else + AUDIOBEAM_SET_FLOAT_WORD( qx, ix - 0x01000000 ); + hz = ( float )0.5f * z - qx; + a = audiobeam_one - qx; + return a - ( hz - ( z * r - x * y ) ); + } +} + + +float audiobeam___kernel_sinf( float x, float y, int iy ) +{ + float z, r, v; + int ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + ix &= 0x7fffffff; + if ( ix < 0x32000000 ) { + if ( ( int )x == 0 ) return x; + } + z = x * x; + v = z * x; + r = audiobeam_S2 + z * ( audiobeam_S3 + z * ( audiobeam_S4 + z * ( audiobeam_S5 + z * audiobeam_S6 ) ) ); + if ( iy == 0 ) return x + v * ( audiobeam_S1 + z * r ); + else return x - ( ( z * ( audiobeam_half * y - v * r ) - y ) - v * audiobeam_S1 ); +} + + +float audiobeam___copysignf( float x, float y ) +{ + unsigned int ix, iy; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + AUDIOBEAM_GET_FLOAT_WORD( iy, y ); + AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x7fffffff ) | ( iy & 0x80000000 ) ); + return x; +} + + +float audiobeam___cosf( float x ) +{ + float y[2], z = 0.0f; + int n, ix; + + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + + ix &= 0x7fffffff; + if ( ix <= 0x3f490fd8 ) return audiobeam___kernel_cosf( x, z ); + + else + if ( ix >= 0x7f800000 ) return x - x; + + else { + y[0] = 0.0; + y[1] = 0.0; + n = audiobeam___ieee754_rem_pio2f( x, y ); + switch ( n & 3 ) { + case 0: + return audiobeam___kernel_cosf( y[0], y[1] ); + case 1: + return -audiobeam___kernel_sinf( y[0], y[1], 1 ); + case 2: + return -audiobeam___kernel_cosf( y[0], y[1] ); + default: + return audiobeam___kernel_sinf( y[0], y[1], 1 ); + } + } +} + + +float audiobeam___fabsf( float x ) +{ + unsigned int ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + AUDIOBEAM_SET_FLOAT_WORD( x, ix & 0x7fffffff ); + return x; +} + + +float audiobeam___floorf( float x ) +{ + int i0, j0; + unsigned int i; + AUDIOBEAM_GET_FLOAT_WORD( i0, x ); + j0 = ( ( i0 >> 23 ) & 0xff ) - 0x7f; + if ( j0 < 23 ) { + if ( j0 < 0 ) { + if ( audiobeam_huge + x > ( float )0.0f ) { + if ( i0 >= 0 ) + i0 = 0; + else + if ( ( i0 & 0x7fffffff ) != 0 ) + i0 = 0xbf800000; + } + } else { + i = ( 0x007fffff ) >> j0; + if ( ( i0 & i ) == 0 ) return x; + if ( audiobeam_huge + x > ( float )0.0f ) { + if ( i0 < 0 ) i0 += ( 0x00800000 ) >> j0; + i0 &= ( ~i ); + } + } + } else { + if ( j0 == 0x80 ) return x + x; + else return x; + } + AUDIOBEAM_SET_FLOAT_WORD( x, i0 ); + return x; +} + + +int audiobeam___isinff ( float x ) +{ + int ix, t; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + t = ix & 0x7fffffff; + t ^= 0x7f800000; + t |= -t; + return ~( t >> 31 ) & ( ix >> 30 ); +} + + +float audiobeam___scalbnf ( float x, int n ) +{ + int k, ix; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + k = ( ix & 0x7f800000 ) >> 23; + if ( k == 0 ) { + if ( ( ix & 0x7fffffff ) == 0 ) return x; + x *= audiobeam_two25; + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + k = ( ( ix & 0x7f800000 ) >> 23 ) - 25; + } + if ( k == 0xff ) return x + x; + k = k + n; + if ( n > 50000 || k > 0xfe ) + return audiobeam_huge * audiobeam___copysignf( audiobeam_huge, + x ); + if ( n < -50000 ) + return audiobeam_tiny * audiobeam___copysignf( audiobeam_tiny, + x ); + if ( k > 0 ) { + AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) ); + return x; + } + if ( k <= -25 ) + return audiobeam_tiny * audiobeam___copysignf( audiobeam_tiny, + x ); + k += 25; + AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) ); + return x * audiobeam_twom25; +} + + +float audiobeam___ceilf( float x ) +{ + int i0, j0; + unsigned int i; + + AUDIOBEAM_GET_FLOAT_WORD( i0, x ); + j0 = ( ( i0 >> 23 ) & 0xff ) - 0x7f; + if ( j0 < 23 ) { + if ( j0 < 0 ) { + if ( audiobeam_huge + x > ( float )0.0 ) { + if ( i0 < 0 ) + i0 = 0x80000000; + else + if ( i0 != 0 ) + i0 = 0x3f800000; + } + } else { + i = ( 0x007fffff ) >> j0; + if ( ( i0 & i ) == 0 ) return x; + if ( audiobeam_huge + x > ( float )0.0 ) { + if ( i0 > 0 ) i0 += ( 0x00800000 ) >> j0; + i0 &= ( ~i ); + } + } + } else { + if ( j0 == 0x80 ) return x + x; + else return x; + } + AUDIOBEAM_SET_FLOAT_WORD( x, i0 ); + return x; +} + + +float audiobeam___ieee754_sqrtf( float x ) +{ + float z; + int sign = ( int )0x80000000; + int ix, s, q, m, t, i; + unsigned int r; + + AUDIOBEAM_GET_FLOAT_WORD( ix, x ); + + if ( ( ix & 0x7f800000 ) == 0x7f800000 ) + return x * x + x; + if ( ix <= 0 ) { + if ( ( ix & ( ~sign ) ) == 0 ) return x; + else + if ( ix < 0 ) + return ( x - x ) / ( x - x ); + } + m = ( ix >> 23 ); + if ( m == 0 ) { + _Pragma( "loopbound min 0 max 0" ) + for ( i = 0; ( ix & 0x00800000 ) == 0; i++ ) + ix <<= 1; + m -= i - 1; + } + m -= 127; + ix = ( ix & 0x007fffff ) | 0x00800000; + if ( m & 1 ) + ix += ix; + m >>= 1; + + ix += ix; + q = s = 0; + r = 0x01000000; + + _Pragma( "loopbound min 25 max 25" ) + while ( r != 0 ) { + t = s + r; + if ( t <= ix ) { + s = t + r; + ix -= t; + q += r; + } + ix += ix; + r >>= 1; + } + + if ( ix != 0 ) { + z = audiobeam_one - audiobeam_tiny; + if ( z >= audiobeam_one ) { + z = audiobeam_one + audiobeam_tiny; + if ( z > audiobeam_one ) + q += 2; + else + q += ( q & 1 ); + } + } + ix = ( q >> 1 ) + 0x3f000000; + ix += ( m << 23 ); + AUDIOBEAM_SET_FLOAT_WORD( z, ix ); + return z; +} diff --git a/baseline/source/audiobeam/audiobeamlibm.h b/baseline/source/audiobeam/audiobeamlibm.h new file mode 100644 index 0000000..b06b563 --- /dev/null +++ b/baseline/source/audiobeam/audiobeamlibm.h @@ -0,0 +1,59 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: quicksortlibm.c + + Author: Ian Lance Taylor + + Function: IEEE754 software library routines. + + Source: Sun Microsystems and Cygnus + + Original name: Unknown + + Changes: No major functional changes. + + License: See audiobeamlibm.c + +*/ + +#ifndef AUDIOBEAM_LIBM +#define AUDIOBEAM_LIBM + +#define audiobeam_M_PI 3.14159265358979323846 + +static const float +audiobeam_one = 1.0f, +audiobeam_tiny = 1.0e-30f, +audiobeam_half = 5.0000000000e-01, /* 0x3f000000 */ +audiobeam_huge = 1.0e30, +audiobeam_two8 = 2.5600000000e+02, /* 0x43800000 */ +audiobeam_twon8 = 3.9062500000e-03, /* 0x3b800000 */ +audiobeam_zero = 0.0; + +#define audiobeam_cos audiobeam___cosf +#define audiobeam_fabs audiobeam___fabsf +#define audiobeam_fabsf audiobeam___fabsf +#define audiobeam_isinf audiobeam___isinff +#define audiobeam_sqrt audiobeam___ieee754_sqrtf +#define audiobeam_ceil audiobeam___ceilf +#define audiobeam_floor audiobeam___floorf + +float audiobeam___copysignf( float x, float y ); +float audiobeam___cosf( float x ); +float audiobeam___fabsf( float x ); +float audiobeam___floorf( float x ); +int audiobeam___ieee754_rem_pio2f( float x, float *y ); +float audiobeam___ieee754_sqrtf( float x ); +int audiobeam___isinff ( float x ); +float audiobeam___kernel_cosf( float x, float y ); +float audiobeam___kernel_sinf( float x, float y, int iy ); +int audiobeam___kernel_rem_pio2f( float *x, float *y, int e0, int nx, + int prec, const int *ipio2 ); +float audiobeam___scalbnf ( float x, int n ); +float audiobeam___ceilf( float x ); +float audiobeam___floorf( float x ); + +#endif // AUDIOBEAM_LIBM diff --git a/baseline/source/audiobeam/audiobeamlibmalloc.c b/baseline/source/audiobeam/audiobeamlibmalloc.c new file mode 100644 index 0000000..50c3073 --- /dev/null +++ b/baseline/source/audiobeam/audiobeamlibmalloc.c @@ -0,0 +1,14 @@ +#include "audiobeamlibmalloc.h" + +#define AUDIOBEAM_HEAP_SIZE 10000 + +static char audiobeam_simulated_heap[AUDIOBEAM_HEAP_SIZE]; +static unsigned int audiobeam_freeHeapPos; + +void *audiobeam_malloc( unsigned int numberOfBytes ) +{ + void *currentPos = ( void * )&audiobeam_simulated_heap[ audiobeam_freeHeapPos ]; + /* Get a 4-byte address for alignment purposes */ + audiobeam_freeHeapPos += ( ( numberOfBytes + 4 ) & ( unsigned int )0xfffffffc ); + return currentPos; +} \ No newline at end of file diff --git a/baseline/source/audiobeam/audiobeamlibmalloc.h b/baseline/source/audiobeam/audiobeamlibmalloc.h new file mode 100644 index 0000000..eccbdb9 --- /dev/null +++ b/baseline/source/audiobeam/audiobeamlibmalloc.h @@ -0,0 +1,27 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: audiobeamlibmalloc.c + + Author: unkown + + Function: Memory allocation. + + Source: Sun Microsystems and Cygnus + + Original name: Unknown + + Changes: No major functional changes. + + License: see license.txt + +*/ + +#ifndef AUDIOBEAM_MALLOC_H +#define AUDIOBEAM_MALLOC_H + +void *audiobeam_malloc( unsigned int numberOfBytes ); + +#endif diff --git a/baseline/source/audiobeam/audiobeamlibmath.h b/baseline/source/audiobeam/audiobeamlibmath.h new file mode 100644 index 0000000..77bda0f --- /dev/null +++ b/baseline/source/audiobeam/audiobeamlibmath.h @@ -0,0 +1,69 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: audiobeamlibmath.h + + Author: Unknown + + Function: IEEE754 software library routines. + + Source: Sun Microsystems + + Original name: math_private.h + + Changes: No major functional changes. + + License: See the terms below. + +*/ + + +/* + ==================================================== + Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + + Developed at SunPro, a Sun Microsystems, Inc. business. + Permission to use, copy, modify, and distribute this + software is freely granted, provided that this notice + is preserved. + ==================================================== +*/ + +/* + from: @(#)fdlibm.h 5.1 93/09/24 +*/ + +#ifndef AUDIOBEAM_MATH_PRIVATE_H_ +#define AUDIOBEAM_MATH_PRIVATE_H_ + +#include "audiobeamlibm.h" + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union { + float value; + unsigned int word; +} audiobeam_ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define AUDIOBEAM_GET_FLOAT_WORD(i,d) \ +{ \ + audiobeam_ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} + +/* Set a float from a 32 bit int. */ + +#define AUDIOBEAM_SET_FLOAT_WORD(d,i) \ +{ \ + audiobeam_ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/baseline/source/audiobeam/changeLog.txt b/baseline/source/audiobeam/changeLog.txt new file mode 100644 index 0000000..b9b8933 --- /dev/null +++ b/baseline/source/audiobeam/changeLog.txt @@ -0,0 +1,36 @@ +File: audiobeam.c +Original provenience: StreamIt + http://groups.csail.mit.edu/cag/streamit/ + +2015-12-29: +- Removed original header comment, replaced by TACLeBench header. +- Renamed libraryfiles according to TACLeBench naming scheme. +- Removed all preprocessor macros, integrated them directly in the source code. +- Added prefix "audiobeam_" to all global symbols. +- Added explicit forward declarations of functions. +- Added an empty init function +- Added preprocessor command to determine if 32 or 64 bit in audiobeamlibmalloc.h +- Added new function audiobeam_return producing a checksum as return value. +- Added new function audiobeam_main according to TACLeBench guidelines. + audiobeam_main is annotated as entry-point for timing analysis. +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: bs_) followed by lowercase letter (e.g., bs_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur \ No newline at end of file diff --git a/baseline/source/audiobeam/license.txt b/baseline/source/audiobeam/license.txt new file mode 100644 index 0000000..7029925 --- /dev/null +++ b/baseline/source/audiobeam/license.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/baseline/source/cjpeg_transupp/ChangeLog.txt b/baseline/source/cjpeg_transupp/ChangeLog.txt new file mode 100644 index 0000000..df4383c --- /dev/null +++ b/baseline/source/cjpeg_transupp/ChangeLog.txt @@ -0,0 +1,36 @@ +File: cjpeg_transupp.c +Original provenience: MediaBench II benchmark suite, + http://euler.slu.edu/~fritts/mediabench (mirror) + +2015-11-03: +- Removed original header comment, replaced by TACLeBench header. +- Removed unnecessary preprocessor macros. +- Removed unnecessary code parts, simplified header files and include + relationships. +- Added prefix "cjpeg_transupp" to all global symbols. +- Added explicit forward declarations of functions. +- Replaced initialization code by TACLeBench-compliant initialization code. +- Added new function cjpeg_transupp_return producing a checksum as return value. +- Added new function cjpeg_transupp_main according to TACLeBench guidelines. + cjpeg_transupp_main is annotated as entry-point for timing analysis. +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: bs_) followed by lowercase letter (e.g., bs_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur diff --git a/baseline/source/cjpeg_transupp/README b/baseline/source/cjpeg_transupp/README new file mode 100644 index 0000000..8dba954 --- /dev/null +++ b/baseline/source/cjpeg_transupp/README @@ -0,0 +1,417 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 6a of 7-Feb-96 +================================= + +This distribution contains the sixth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +Serious users of this software (particularly those incorporating it into +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to +our electronic mailing list. Mailing list members are notified of updates +and have a chance to participate in technical discussions, etc. + +This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim +Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi, +Ge' Weijers, and other members of the Independent JPEG Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +RELATED SOFTWARE Other stuff you should get. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.doc How to configure and install the IJG software. + usage.doc Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.doc). + wizard.doc Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.doc How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.doc Overview of the JPEG library's internal structure. + filelist.doc Road map of IJG files. + coderules.doc Coding style rules --- please read if you contribute code. + +Please read at least the files install.doc and usage.doc. Useful information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image compression and +decompression. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. JPEG is intended for compressing +"real-world" scenes; line drawings, cartoons and other non-realistic images +are not its strong suit. JPEG is lossy, meaning that the output image is not +exactly identical to the input image. Hence you must not use JPEG if you +have to have identical output bits. However, on typical photographic images, +very good compression levels can be obtained with no visible change, and +remarkably high compression levels are possible if you can tolerate a +low-quality image. For more details, see the references, or just experiment +with various compression settings. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +For legal reasons, we are not distributing code for the arithmetic-coding +variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting +the hierarchical or lossless processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. We have also included +"jpegtran", a utility for lossless transcoding between different JPEG +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for +inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + +Lossless image transformation routines. These routines work on DCT coefficient +arrays and thus do not require any lossy decompression or recompression of the +image. Thanks to Guido Vollbeding for the initial design and code of this +feature. + +Horizontal flipping is done in-place, using a single top-to-bottom pass through +the virtual source array. It will thus be much the fastest option for images +larger than main memory. + +The other routines require a set of destination virtual arrays, so they need +twice as much memory as jpegtran normally does. The destination arrays are +always written in normal scan order (top to bottom) because the virtual array +manager expects this. The source arrays will be scanned in the corresponding +order, which means multiple passes through the source arrays for most of the +transforms. That could result in much thrashing if the image is larger than main +memory. + +Some notes about the operating environment of the individual transform routines: +1. Both the source and destination virtual arrays are allocated from the source + JPEG object, and therefore should be manipulated by calling the source's + memory manager. +2. The destination's component count should be used. It may be smaller than the + source's when forcing to grayscale. +3. Likewise the destination's sampling factors should be used. When forcing to + grayscale the destination's sampling factors will be all 1, and we may as + well take that as the effective iMCU size. +4. When "trim" is in effect, the destination's dimensions will be the trimmed + values but the source's will be untrimmed. +5. All the routines assume that the source and destination buffers are padded + out to a full iMCU boundary. This is true, although for the source buffer it + is an undocumented property of jdcoefct.c. +Notes 2,3,4 boil down to this: generally we should use the destination's +dimensions and ignore the source's. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-1996, Thomas G. Lane. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The configuration script "configure" was produced with GNU Autoconf. It +is copyright by the Free Software Foundation but is freely distributable. + +It appears that the arithmetic coding option of the JPEG spec is covered by +patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot +legally be used without obtaining one or more licenses. For this reason, +support for arithmetic coding has been removed from the free JPEG software. +(Since arithmetic coding provides only a marginal gain over the unpatented +Huffman mode, it is unlikely that very many implementations will support it.) +So far as we are aware, there are no patent restrictions on the remaining +code. + +WARNING: Unisys has begun to enforce their patent on LZW compression against +GIF encoders and decoders. You will need a license from Unisys to use the +included rdgif.c or wrgif.c files in a commercial or shareware application. +At this time, Unisys is not enforcing their patent against freeware, so +distribution of this package remains legal. However, we intend to remove +GIF support from the IJG package as soon as a suitable replacement format +becomes reasonably popular. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." + + +REFERENCES +========== + +We highly recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article +is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and +IEEE, and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood +City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and +example C code for a multitude of compression methods including JPEG. It is +an excellent source if you are comfortable reading C code but don't know much +about data compression in general. The book's JPEG sample code is far from +industrial-strength, but when you are ready to look at a full implementation, +you've got one here... + +The best full description of JPEG is the textbook "JPEG Still Image Data +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. +The book includes the complete text of the ISO JPEG standards (DIS 10918-1 +and draft DIS 10918-2). This is by far the most complete exposition of JPEG +in existence, and we highly recommend it. + +The JPEG standard itself is not available electronically; you must order a +paper copy through ISO or ITU. (Unless you feel a need to own a certified +official copy, we recommend buying the Pennebaker and Mitchell book instead; +it's much cheaper and includes a great deal of useful explanatory material.) +In the USA, copies of the standard may be ordered from ANSI Sales at (212) +642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI +doesn't take credit card orders, but Global does.) It's not cheap: as of +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% +shipping/handling. The standard is divided into two parts, Part 1 being the +actual specification, while Part 2 covers compliance testing methods. Part 1 +is titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. + +Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO +document. Part 3 is undergoing ISO balloting and is expected to be approved +by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T +T.84. IJG currently does not support any Part 3 extensions. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. A copy of the JFIF spec is available from: + Literature Department + C-Cube Microsystems, Inc. + 1778 McCarthy Blvd. + Milpitas, CA 95035 + phone (408) 944-6300, fax (408) 944-6314 +A PostScript version of this document is available at ftp.uu.net, file +graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube +mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" +to the server to obtain the JFIF document; send the message "help" if you have +trouble. + +The TIFF 6.0 file format specification can be obtained by FTP from sgi.com +(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed +copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from sgi.com or +from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of +the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. libtiff is available +from sgi.com:/graphics/tiff/. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is ftp.uu.net (Internet +address 192.48.96.9). The most recent released version can always be found +there in directory graphics/jpeg. This particular version will be archived +as graphics/jpeg/jpegsrc.v6a.tar.gz. If you are on the Internet, you +can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't +have FTP access, UUNET's archives are also available via UUCP; contact +help@uunet.uu.net for information on retrieving files that way. + +Numerous Internet sites maintain copies of the UUNET files. However, only +ftp.uu.net is guaranteed to have the latest official version. + +You can also obtain this software in DOS-compatible "zip" archive format from +the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe +in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools". +Again, these versions may sometimes lag behind the ftp.uu.net release. + +The JPEG FAQ (Frequently Asked Questions) article is a useful source of +general information about JPEG. It is updated constantly and therefore is +not included in this distribution. The FAQ is posted every two weeks to +Usenet newsgroups comp.graphics.misc, news.answers, and other groups. +You can always obtain the latest version from the news.answers archive at +rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and +.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +RELATED SOFTWARE +================ + +Numerous viewing and image manipulation programs now support JPEG. (Quite a +few of them use this library to do so.) The JPEG FAQ described above lists +some of the more popular free and shareware viewers, and tells where to +obtain them on Internet. + +If you are on a Unix machine, we highly recommend Jef Poskanzer's free +PBMPLUS image software, which provides many useful operations on PPM-format +image files. In particular, it can convert PPM images to and from a wide +range of other formats. You can obtain this package by FTP from ftp.x.org +(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also +a newer update of this package called NETPBM, available from +wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/. +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software +is; you are likely to have difficulty making it work on any non-Unix machine. + +A different free JPEG implementation, written by the PVRG group at Stanford, +is available from havefun.stanford.edu in directory pub/jpeg. This program +is designed for research and experimentation rather than production use; +it is slower, harder to use, and less portable than the IJG code, but it +is easier to read and modify. Also, the PVRG code supports lossless JPEG, +which we do not. + + +FILE FORMAT WARS +================ + +Some JPEG programs produce files that are not compatible with our library. +The root of the problem is that the ISO JPEG committee failed to specify a +concrete file format. Some vendors "filled in the blanks" on their own, +creating proprietary formats that no one else could read. (For example, none +of the early commercial JPEG implementations for the Macintosh were able to +exchange compressed files.) + +The file format we have adopted is called JFIF (see REFERENCES). This format +has been agreed to by a number of major commercial JPEG vendors, and it has +become the de facto standard. JFIF is a minimal or "low end" representation. +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF +Technical Note #2) for "high end" applications that need to record a lot of +additional data about an image. TIFF/JPEG is fairly new and not yet widely +supported, unfortunately. + +The upcoming JPEG Part 3 standard defines a file format called SPIFF. +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should +be able to read the most common variant of SPIFF. SPIFF has some technical +advantages over JFIF, but its major claim to fame is simply that it is an +official standard rather than an informal one. At this point it is unclear +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto +standard. IJG intends to support SPIFF once the standard is frozen, but we +have not decided whether it should become our default output format or not. +(In any case, our decoder will remain capable of reading JFIF indefinitely.) + +Various proprietary file formats incorporating JPEG compression also exist. +We have little or no sympathy for the existence of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, open format standards for JPEG files. Don't +use a proprietary file format! + + +TO DO +===== + +In future versions, we are considering supporting some of the upcoming JPEG +Part 3 extensions --- principally, variable quantization and the SPIFF file +format. + +Tuning the software for better behavior at low quality/high compression +settings is also of interest. The current method for scaling the +quantization tables is known not to be very good at low Q values. + +As always, speeding things up is high on our priority list. + +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/baseline/source/cjpeg_transupp/cjpeg_transupp.c b/baseline/source/cjpeg_transupp/cjpeg_transupp.c new file mode 100644 index 0000000..e77d15b --- /dev/null +++ b/baseline/source/cjpeg_transupp/cjpeg_transupp.c @@ -0,0 +1,718 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: cjpeg_transupp + + Author: Thomas G. Lane + + Function: This file contains image transformation routines and other utility + code used by the jpegtran sample application. These are NOT part of the core + JPEG library. But we keep these routines separate from jpegtran.c to ease + the task of maintaining jpegtran-like programs that have other user + interfaces. + + Source: MediaBench II + http://euler.slu.edu/~fritts/mediabench (mirror) + + Original name: cjpeg + + Changes: No major functional changes. + + License: See the accompanying README file. + +*/ + + +/* + Include section +*/ + +#include "../extra.h" +#include "jpeglib.h" + + +/* + Forward declaration of functions +*/ + +void cjpeg_transupp_initSeed( void ); +signed char cjpeg_transupp_randomInteger( void ); +void cjpeg_transupp_init( void ); +int cjpeg_transupp_return( void ); +void cjpeg_transupp_do_flip_v( j_compress_ptr ); +void cjpeg_transupp_do_rot_90( j_compress_ptr ); +void cjpeg_transupp_do_rot_180( j_compress_ptr ); +void cjpeg_transupp_do_rot_270( j_compress_ptr ); +void cjpeg_transupp_do_transverse( j_compress_ptr ); +void cjpeg_transupp_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +volatile int cjpeg_transupp_seed; + +signed char cjpeg_transupp_input[ 256 ]; +signed char cjpeg_transupp_input2[ 80 ]; +signed char cjpeg_transupp_input3[ 65 ]; +signed char cjpeg_transupp_input3_2[ 65 ]; +signed char cjpeg_transupp_input4[ 64 ]; +signed char cjpeg_transupp_input5[ 65 ]; +signed char cjpeg_transupp_input5_2[ 65 ]; + +/* Output arrays replace writing of results into a file. */ +signed char cjpeg_transupp_output_data[ 512 ]; +signed char cjpeg_transupp_output_data2[ 512 ]; +signed char cjpeg_transupp_output_data3[ 512 ]; +signed char cjpeg_transupp_output_data4[ 512 ]; +signed char cjpeg_transupp_output_data5[ 512 ]; + +struct jpeg_compress_struct cjpeg_transupp_dstinfo; + + +/* + Initialization- and return-value-related functions +*/ + +void cjpeg_transupp_initSeed( void ) +{ + cjpeg_transupp_seed = 0; +} + + +/* + cjpeg_transupp_RandomInteger generates random integers between -128 and 127. +*/ +signed char cjpeg_transupp_randomInteger( void ) +{ + cjpeg_transupp_seed = ( ( ( cjpeg_transupp_seed * 133 ) + 81 ) % 256 ) - 128; + return( cjpeg_transupp_seed ); +} + + +void cjpeg_transupp_init( void ) +{ + register int i; + + + cjpeg_transupp_dstinfo.max_h_samp_factor = 2; + cjpeg_transupp_dstinfo.max_v_samp_factor = 2; + cjpeg_transupp_dstinfo.num_components = 3; + + cjpeg_transupp_initSeed(); + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) + cjpeg_transupp_input[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 80 max 80" ) + for ( i = 0; i < 80; i++ ) + cjpeg_transupp_input2[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input3[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input3_2[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 64 max 64" ) + for ( i = 0; i < 64; i++ ) + cjpeg_transupp_input4[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input5[ i ] = cjpeg_transupp_randomInteger(); + + _Pragma( "loopbound min 65 max 65" ) + for ( i = 0; i < 65; i++ ) + cjpeg_transupp_input5_2[ i ] = cjpeg_transupp_randomInteger(); +} + + +int cjpeg_transupp_return( void ) +{ + int checksum = 0; + unsigned int i; + + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data2[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data3[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data4[ i ]; + + _Pragma( "loopbound min 512 max 512" ) + for ( i = 0; i < 512; i++ ) + checksum += cjpeg_transupp_output_data5[ i ]; + + return( checksum ); +} + + +/* + Algorithm core functions +*/ + +/* + Vertical flip +*/ +void cjpeg_transupp_do_flip_v( j_compress_ptr dstinfo ) +{ + unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + + /* + We output into a separate array because we can't touch different rows of the + source virtual array simultaneously. Otherwise, this is a pretty + straightforward analog of horizontal flip. + Within a DCT block, vertical mirroring is done by changing the signs of + odd-numbered rows. + Partial iMCUs at the bottom edge are copied verbatim. + */ + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 19; + unsigned int compptr_width_in_blocks = 29; + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; + ci++, compptr_v_samp_factor = 1, compptr_width_in_blocks = 15 ) { + comp_height = MCU_rows * compptr_v_samp_factor; + + compptr_height_in_blocks = 10; + _Pragma( "loopbound min 2 max 10" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + + _Pragma( "loopbound min 1 max 8" ) + for ( offset_y = 0; offset_y < compptr_v_samp_factor; offset_y++ ) { + if ( dst_blk_y < comp_height ) { + + /* Row is within the mirrorable area. */ + _Pragma( "loopbound min 15 max 29" ) + for ( dst_blk_x = 0; dst_blk_x < compptr_width_in_blocks; + dst_blk_x++ ) { + + src_ptr = cjpeg_transupp_input; + dst_ptr = cjpeg_transupp_output_data; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i += 2 ) { + + /* copy even row */ + j = 0; + _Pragma( "loopbound min 8 max 8" ) + do { + if ( dst_blk_x < comp_height ) + *dst_ptr++ = *src_ptr++; + j++; + } while ( j < DCTSIZE ); + + /* copy odd row with sign change */ + j = 0; + _Pragma( "loopbound min 8 max 8" ) + do { + if ( dst_blk_x < comp_height ) + *dst_ptr++ = - *src_ptr++; + j++; + } while ( j < DCTSIZE ); + } + } + } + } + } + } +} + + +/* + 90 degree rotation is equivalent to + 1. Transposing the image; + 2. Horizontal mirroring. + These two steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_rot_90( j_compress_ptr dstinfo ) +{ + unsigned int MCU_cols, comp_width, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + + /* + Because of the horizontal mirror step, we can't process partial iMCUs at the + (output) right edge properly. They just get transposed and not mirrored. + */ + MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE ); + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 29; + unsigned int compptr_width_in_blocks = 19; + + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; + ci++, compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) { + + comp_width = MCU_cols * compptr_h_samp_factor; + + _Pragma( "loopbound min 4 max 15" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) { + dst_blk_x = 0; + _Pragma( "loopbound min 10 max 10" ) + for ( ; dst_blk_x < compptr_width_in_blocks; + dst_blk_x += compptr_h_samp_factor ) { + + offset_x = 0; + _Pragma( "loopbound min 1 max 2" ) + for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) { + + src_ptr = cjpeg_transupp_input2; + + if ( dst_blk_x < comp_width ) { + + /* Block is within the mirrorable area. */ + dst_ptr = cjpeg_transupp_output_data2; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + + i++; + + _Pragma( "loopbound min 8 max 8" ) + for ( j = 0; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } else { + /* Edge blocks are transposed but not mirrored. */ + dst_ptr = cjpeg_transupp_output_data2; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + } + } + } + } + } +} + + +/* + 270 degree rotation is equivalent to + 1. Horizontal mirroring; + 2. Transposing the image. + These two steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_rot_270( j_compress_ptr dstinfo ) +{ + unsigned int MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + + /* + Because of the horizontal mirror step, we can't process partial iMCUs at the + (output) bottom edge properly. They just get transposed and not mirrored. + */ + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 29; + unsigned int compptr_width_in_blocks = 19; + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; + ci++, compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) { + + comp_height = MCU_rows * compptr_v_samp_factor; + + _Pragma( "loopbound min 4 max 15" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) { + dst_blk_x = 0; + _Pragma( "loopbound min 10 max 10" ) + for ( ; dst_blk_x < compptr_width_in_blocks; + dst_blk_x += compptr_h_samp_factor ) { + + offset_x = 0; + _Pragma( "loopbound min 1 max 2" ) + for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) { + + dst_ptr = cjpeg_transupp_output_data3; + + if ( dst_blk_y < comp_height ) { + + /* Block is within the mirrorable area. */ + src_ptr = cjpeg_transupp_input3; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j++ ) { + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } + } else { + + /* Edge blocks are transposed but not mirrored. */ + src_ptr = cjpeg_transupp_input3_2; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_height ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + } + } + } + } + } +} + + +/* + 180 degree rotation is equivalent to + 1. Vertical mirroring; + 2. Horizontal mirroring. + These two steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_rot_180( j_compress_ptr dstinfo ) +{ + unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, + dst_blk_y; + int ci, i, j, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_width_in_blocks = 29; + unsigned int compptr_height_in_blocks = 19; + + + MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE ); + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; ci++, + compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_width_in_blocks = 15, compptr_height_in_blocks = 10 ) { + + comp_width = MCU_cols * compptr_h_samp_factor; + comp_height = MCU_rows * compptr_v_samp_factor; + + _Pragma( "loopbound min 3 max 10" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + for ( ; offset_y < compptr_v_samp_factor; offset_y++ ) { + if ( dst_blk_y < comp_height ) { + + /* Row is within the mirrorable area. */ + + /* Process the blocks that can be mirrored both ways. */ + _Pragma( "loopbound min 14 max 28" ) + for ( dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++ ) { + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i += 2 ) { + j = 0; + /* For even row, negate every odd column. */ + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j += 2 ) { + if ( dst_blk_x < comp_height ) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + } + } + + j = 0; + /* For odd row, negate every even column. */ + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j += 2 ) { + if ( dst_blk_x < comp_height ) { + *dst_ptr++ = - *src_ptr++; + *dst_ptr++ = *src_ptr++; + } + } + } + } + + /* Any remaining right-edge blocks are only mirrored vertically. */ + _Pragma( "loopbound min 1 max 1" ) + for ( ; dst_blk_x < compptr_width_in_blocks; dst_blk_x++ ) { + + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i += 2 ) { + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + *dst_ptr++ = *src_ptr++; + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + *dst_ptr++ = - *src_ptr++; + } + } + } else { + + /* Remaining rows are just mirrored horizontally. */ + dst_blk_x = 0; + /* Process the blocks that can be mirrored. */ + _Pragma( "loopbound min 14 max 28" ) + do { + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + + i = 0; + _Pragma( "loopbound min 32 max 32" ) + while ( i < DCTSIZE2 ) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = - *src_ptr++; + i += 2; + dst_ptr += 0; + } + dst_blk_x++; + dst_ptr += 0; + } while ( dst_blk_x < comp_width ); + + /* Any remaining right-edge blocks are only copied. */ + _Pragma( "loopbound min 1 max 1" ) + for ( ; dst_blk_x < compptr_width_in_blocks; dst_blk_x++ ) { + + dst_ptr = cjpeg_transupp_output_data4; + src_ptr = cjpeg_transupp_input4; + _Pragma( "loopbound min 64 max 64" ) + do { + *dst_ptr++ = *src_ptr++; + i++; + } while ( i < DCTSIZE2 ); + } + } + } + } + } +} + + +/* + Transverse transpose is equivalent to + 1. 180 degree rotation; + 2. Transposition; + or + 1. Horizontal mirroring; + 2. Transposition; + 3. Horizontal mirroring. + These steps are merged into a single processing routine. +*/ +void cjpeg_transupp_do_transverse( j_compress_ptr dstinfo ) +{ + unsigned int MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, + dst_blk_y; + int ci, i, j, offset_x, offset_y; + JCOEFPTR src_ptr, dst_ptr; + + int compptr_h_samp_factor = 2; + int compptr_v_samp_factor = 8; + unsigned int compptr_height_in_blocks = 29; + unsigned int compptr_width_in_blocks = 19; + + + MCU_cols = dstinfo->image_width / ( dstinfo->max_h_samp_factor * DCTSIZE ); + MCU_rows = dstinfo->image_height / ( dstinfo->max_v_samp_factor * DCTSIZE ); + + _Pragma( "loopbound min 3 max 3" ) + for ( ci = 0; ci < dstinfo->num_components; ci++, + compptr_h_samp_factor = compptr_v_samp_factor = 1, + compptr_height_in_blocks = 15, compptr_width_in_blocks = 10 ) { + + comp_width = MCU_cols * compptr_h_samp_factor; + comp_height = MCU_rows * compptr_v_samp_factor; + + _Pragma( "loopbound min 4 max 15" ) + for ( dst_blk_y = 0; dst_blk_y < compptr_height_in_blocks; + dst_blk_y += compptr_v_samp_factor ) { + offset_y = 0; + _Pragma( "loopbound min 1 max 8" ) + do { + dst_blk_x = 0; + _Pragma( "loopbound min 10 max 10" ) + do { + offset_x = 0; + _Pragma( "loopbound min 1 max 2" ) + for ( ; offset_x < compptr_h_samp_factor; offset_x++ ) { + + if ( dst_blk_y < comp_height ) { + src_ptr = cjpeg_transupp_input5; + + if ( dst_blk_x < comp_width ) { + /* Block is within the mirrorable area. */ + dst_ptr = cjpeg_transupp_output_data5; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + i++; + _Pragma( "loopbound min 4 max 4" ) + for ( j = 0; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + } else { + /* Right-edge blocks are mirrored in y only */ + dst_ptr = cjpeg_transupp_output_data5; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; j < DCTSIZE; j++ ) { + if ( dst_blk_y < comp_width ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + j++; + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } + } + } else { + src_ptr = cjpeg_transupp_input5_2; + + if ( dst_blk_x < comp_width ) { + /* Bottom-edge blocks are mirrored in x only */ + dst_ptr = cjpeg_transupp_output_data5; + + _Pragma( "loopbound min 4 max 4" ) + for ( i = 0; i < DCTSIZE; i++ ) { + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + i++; + _Pragma( "loopbound min 8 max 8" ) + for ( j = 0; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = -src_ptr[ i * DCTSIZE + j ]; + } + } else { + /* At lower right corner, just transpose, no mirroring */ + dst_ptr = cjpeg_transupp_output_data5; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 0; i < DCTSIZE; i++ ) + j = 0; + _Pragma( "loopbound min 8 max 8" ) + for ( ; j < DCTSIZE; j++ ) + dst_ptr[ j * DCTSIZE + i ] = src_ptr[ i * DCTSIZE + j ]; + } + } + dst_blk_x += compptr_h_samp_factor; + } + } while ( dst_blk_x < compptr_width_in_blocks ); + offset_y++; + } while ( offset_y < compptr_v_samp_factor ); + } + } +} + + +/* + Main functions +*/ + +void _Pragma ( "entrypoint" ) cjpeg_transupp_main( void ) +{ + cjpeg_transupp_dstinfo.image_width = 227; + cjpeg_transupp_dstinfo.image_height = 149; + + cjpeg_transupp_do_flip_v( &cjpeg_transupp_dstinfo ); + + cjpeg_transupp_dstinfo.image_width = 149; + cjpeg_transupp_dstinfo.image_height = 227; + + cjpeg_transupp_do_rot_90( &cjpeg_transupp_dstinfo ); + cjpeg_transupp_do_rot_270( &cjpeg_transupp_dstinfo ); + + cjpeg_transupp_dstinfo.image_width = 227; + cjpeg_transupp_dstinfo.image_height = 149; + + cjpeg_transupp_do_rot_180( &cjpeg_transupp_dstinfo ); + + cjpeg_transupp_dstinfo.image_width = 149; + cjpeg_transupp_dstinfo.image_height = 227; + + cjpeg_transupp_do_transverse( &cjpeg_transupp_dstinfo ); +} + + +int main(int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsCompletecomp_info[] */ + int component_index; + + /* horizontal sampling factor (1..4) */ + int h_samp_factor; + + /* vertical sampling factor (1..4) */ + int v_samp_factor; + + /* quantization table selector (0..3) */ + int quant_tbl_no; + + /* + These values may vary between scans. For compression, they must be supplied + by parameter setup; for decompression, they are read from the SOS marker. + The decompressor output side may not use these variables. + */ + + /* DC entropy table selector (0..3) */ + int dc_tbl_no; + + /* AC entropy table selector (0..3) */ + int ac_tbl_no; + + /* Remaining fields should be treated as private by applications. */ + + /* + These values are computed during compression or decompression startup: + Component's size in DCT blocks. Any dummy blocks added to complete an MCU + are not counted; therefore these values do not depend on whether a scan is + interleaved or not. + */ + unsigned int width_in_blocks; + unsigned int height_in_blocks; + + /* + Size of a DCT block in samples. Always DCTSIZE for compression. For + decompression this is the size of the output from one DCT block, reflecting + any scaling we choose to apply during the IDCT step. Values of 1,2,4,8 are + likely to be supported. Note that different components may receive different + IDCT scalings. + */ + int DCT_scaled_size; + + /* + The downsampled dimensions are the component's actual, unpadded number of + samples at the main buffer (preprocessing/compression interface), thus + downsampled_width = ceil(image_width * Hi/Hmax) and similarly for height. + For decompression, IDCT scaling is included, so + downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + + /* actual width in samples */ + unsigned int downsampled_width; + + /* actual height in samples */ + unsigned int downsampled_height; + + /* + This flag is used only for decompression. In cases where some of the + components will be ignored (eg grayscale output from YCbCr image), we can + skip most computations for the unused components. + */ + + /* do we need the value of this component? */ + int component_needed; + + /* + These values are computed before starting a scan of the component. The + decompressor output side may not use these variables. + */ + + /* number of blocks per MCU, horizontally */ + int MCU_width; + + /* number of blocks per MCU, vertically */ + int MCU_height; + + /* MCU_width * MCU_height */ + int MCU_blocks; + + /* MCU width in samples, MCU_width*DCT_scaled_size */ + int MCU_sample_width; + + /* # of non-dummy blocks across in last MCU */ + int last_col_width; + + /* # of non-dummy blocks down in last MCU */ + int last_row_height; + + /* + Saved quantization table for component; (void*)0 if none yet saved. See + jdinput.c comments about the need for this information. This field is + currently used only for decompression. + */ + JQUANT_TBL *quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void *dct_table; +} jpeg_component_info; + + +/* + The script for encoding a multiple-scan file is an array of these: +*/ + +typedef struct { + /* number of components encoded in this scan */ + int comps_in_scan; + + /* their SOF/comp_info[] indexes */ + int component_index[ 4 ]; + + /* progressive JPEG spectral selection parms */ + int Ss, Se; + + /* progressive JPEG successive approx. parms */ + int Ah, Al; +} jpeg_scan_info; + + +/* + Known color spaces. +*/ + +typedef enum { + /* error/unspecified */ + JCS_UNKNOWN, + + /* monochrome */ + JCS_GRAYSCALE, + + /* red/green/blue */ + JCS_RGB, + + /* Y/Cb/Cr (also known as YUV) */ + JCS_YCbCr, + + /* C/M/Y/K */ + JCS_CMYK, + + /* Y/Cb/Cr/K */ + JCS_YCCK +} J_COLOR_SPACE; + + +/* + DCT/IDCT algorithm options. +*/ + +typedef enum { + /* slow but accurate integer algorithm */ + JDCT_ISLOW, + + /* faster, less accurate integer method */ + JDCT_IFAST, + + /* floating-point: accurate, fast on fast HW */ + JDCT_FLOAT +} J_DCT_METHOD; + + +/* + Common fields between JPEG compression and decompression master structs. +*/ + +#define jpeg_common_fields \ + /* Error handler module */\ + struct jpeg_error_mgr *err; \ + /* Memory manager module */\ + struct jpeg_memory_mgr *mem; \ + /* Progress monitor, or (void*)0 if none */\ + struct jpeg_progress_mgr *progress; \ + /* Available for use by application */\ + void *client_data; \ + /* So common code can tell which is which */\ + int is_decompressor; \ + /* For checking call sequence validity */\ + int global_state + + +/* + Routines that are to be used by both halves of the library are declared to + receive a pointer to this structure. There are no actual instances of + jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. +*/ + +struct jpeg_common_struct { + /* Fields common to both master struct types */ + jpeg_common_fields; + + /* + Additional fields follow in an actual jpeg_compress_struct or + jpeg_decompress_struct. All three structs must agree on these initial + fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct *j_common_ptr; +typedef struct jpeg_compress_struct *j_compress_ptr; +typedef struct jpeg_decompress_struct *j_decompress_ptr; + + +/* + Master record for a compression instance +*/ + +struct jpeg_compress_struct { + /* Fields shared with jpeg_decompress_struct */ + jpeg_common_fields; + + /* Destination for compressed data */ + struct jpeg_destination_mgr *dest; + + /* + Description of source image --- these fields must be filled in by outer + application before starting compression. in_color_space must be correct + before you can even call jpeg_set_defaults(). + */ + + /* input image width */ + unsigned int image_width; + + /* input image height */ + unsigned int image_height; + + /* # of color components in input image */ + int input_components; + + /* colorspace of input image */ + J_COLOR_SPACE in_color_space; + + /* image gamma of input image */ + double input_gamma; + + /* + Compression parameters --- these fields must be set before calling + jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + initialize everything to reasonable defaults, then changing anything the + application specifically wants to change. That way you won't get burnt when + new parameters are added. Also note that there are several helper routines + to simplify changing parameters. + */ + + /* bits of precision in image data */ + int data_precision; + + /* # of color components in JPEG image */ + int num_components; + + /* colorspace of JPEG image */ + J_COLOR_SPACE jpeg_color_space; + + /* comp_info[i] describes component that appears i'th in SOF */ + jpeg_component_info *comp_info; + + /* ptrs to coefficient quantization tables, or (void*)0 if not defined */ + JQUANT_TBL *quant_tbl_ptrs[ 4 ]; + + /* ptrs to Huffman coding tables, or (void*)0 if not defined */ + JHUFF_TBL *dc_huff_tbl_ptrs[ 4 ]; + JHUFF_TBL *ac_huff_tbl_ptrs[ 4 ]; + + /* L values for DC arith-coding tables */ + unsigned char arith_dc_L[ 16 ]; + + /* U values for DC arith-coding tables */ + unsigned char arith_dc_U[ 16 ]; + + /* Kx values for AC arith-coding tables */ + unsigned char arith_ac_K[ 16 ]; + + /* # of entries in scan_info array */ + int num_scans; + + /* + script for multi-scan file, or (void*)0 + The default value of scan_info is (void*)0, which causes a single-scan + sequential JPEG file to be emitted. To create a multi-scan file, set + num_scans and scan_info to point to an array of scan definitions. + */ + const jpeg_scan_info *scan_info; + + /* 1=caller supplies downsampled data */ + int raw_data_in; + + /* 1=arithmetic coding, 0=Huffman */ + int arith_code; + + /* 1=optimize entropy encoding parms */ + int optimize_coding; + + /* 1=first samples are cosited */ + int CCIR601_sampling; + + /* 1..100, or 0 for no input smoothing */ + int smoothing_factor; + + /* DCT algorithm selector */ + J_DCT_METHOD dct_method; + + + /* + The restart interval can be specified in absolute MCUs by setting + restart_interval, or in MCU rows by setting restart_in_rows (in which case + the correct restart_interval will be figured for each scan). + */ + + /* MCUs per restart, or 0 for no restart */ + unsigned int restart_interval; + + /* if > 0, MCU rows per restart interval */ + int restart_in_rows; + + + /* + Parameters controlling emission of special markers. + */ + + /* should a JFIF marker be written? */ + int write_JFIF_header; + + /* What to write for the JFIF version number */ + unsigned char JFIF_major_version; + unsigned char JFIF_minor_version; + + /* + These three values are not used by the JPEG code, merely copied into the + JFIF APP0 marker. density_unit can be 0 for unknown, 1 for dots/inch, or 2 + for dots/cm. Note that the pixel aspect ratio is defined by + X_density/Y_density even when density_unit=0. + */ + + /* JFIF code for pixel size units */ + unsigned char density_unit; + + /* Horizontal pixel density */ + unsigned short X_density; + + /* Vertical pixel density */ + unsigned short Y_density; + + /* should an Adobe marker be written? */ + int write_Adobe_marker; + + /* + State variable: index of next scanline to be written to + jpeg_write_scanlines(). Application may use this to control its processing + loop, e.g., "while (next_scanline < image_height)". + */ + + /* 0 .. image_height-1 */ + unsigned int next_scanline; + + + /* + Remaining fields are known throughout compressor, but generally should not + be touched by a surrounding application. + */ + + /* + These fields are computed during compression startup + */ + + /* 1 if scan script uses progressive mode */ + int progressive_mode; + + /* largest h_samp_factor */ + int max_h_samp_factor; + + /* largest v_samp_factor */ + int max_v_samp_factor; + + /* + # of iMCU rows to be input to coef ctlr + The coefficient controller receives data in units of MCU rows as defined for + fully interleaved scans (whether the JPEG file is interleaved or not). There + are v_samp_factor * DCTSIZE sample rows of each component in an "iMCU" + (interleaved MCU) row. + */ + unsigned int total_iMCU_rows; + + /* + These fields are valid during any one scan. They describe the components + and MCUs actually appearing in the scan. + */ + + /* # of JPEG components in this scan */ + int comps_in_scan; + + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + jpeg_component_info *cur_comp_info[ 4 ]; + + /* # of MCUs across the image */ + unsigned int MCUs_per_row; + + /* # of MCU rows in the image */ + unsigned int MCU_rows_in_scan; + + /* # of DCT blocks per MCU */ + int blocks_in_MCU; + + /* + MCU_membership[i] is index in cur_comp_info of component owning i'th block + in an MCU + */ + int MCU_membership[ 10 ]; + + /* progressive JPEG parameters for scan */ + int Ss, Se, Ah, Al; + + /* + Links to compression subobjects (methods and private variables of modules) + */ + + struct jpeg_comp_master *master; + struct jpeg_c_main_controller *main; + struct jpeg_c_prep_controller *prep; + struct jpeg_c_coef_controller *coef; + struct jpeg_marker_writer *marker; + struct jpeg_color_converter *cconvert; + struct jpeg_downsampler *downsample; + struct jpeg_forward_dct *fdct; + struct jpeg_entropy_encoder *entropy; + + /* workspace for jpeg_simple_progression */ + jpeg_scan_info *script_space; + + int script_space_size; +}; + + +/* + "Object" declarations for JPEG modules that may be supplied or called directly + by the surrounding application. As with all objects in the JPEG library, these + structs only define the publicly visible methods and state variables of a + module. Additional private fields may exist after the public ones. +*/ + +/* + Error handler object +*/ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + void ( *error_exit ) ( j_common_ptr cinfo ); + + /* Conditionally emit a trace or warning message */ + void ( *emit_message ) ( j_common_ptr cinfo, int msg_level ); + + /* Routine that actually outputs a trace or error message */ + void ( *output_message ) ( j_common_ptr cinfo ); + + /* Format a message string for the most recent JPEG error or message */ + void ( *format_message ) ( j_common_ptr cinfo, char *buffer ); + + /* Reset error state variables at start of a new image */ + void ( *reset_error_mgr ) ( j_common_ptr cinfo ); + + /* + The message ID code and any parameters are saved here. A message can have + one string parameter or up to 8 int parameters. + */ + int msg_code; + + union { + int i[ 8 ]; + char s[ 80 ]; + } msg_parm; + + + /* + Standard state variables for error facility + */ + + /* max msg_level that will be displayed */ + int trace_level; + + /* + For recoverable corrupt-data errors, we emit a warning message, but keep + going unless emit_message chooses to abort. emit_message should count + warnings in num_warnings. The surrounding application can check for bad data + by seeing if num_warnings is nonzero at the end of processing. + */ + + /* number of corrupt-data warnings */ + long num_warnings; + + /* + These fields point to the table(s) of error message strings. An application + can change the table pointer to switch to a different message list + (typically, to change the language in which errors are reported). Some + applications may wish to add additional error codes that will be handled by + the JPEG library error mechanism; the second table pointer is used for this + purpose. + + First table includes all errors generated by JPEG library itself. Error + code 0 is reserved for a "no such error string" message. + */ + + /* Library errors */ + const char *const *jpeg_message_table; + + /* Table contains strings 0..last_jpeg_message */ + int last_jpeg_message; + + /* + Second table can be added by application (see cjpeg/djpeg for example). It + contains strings numbered first_addon_message..last_addon_message. + */ + + /* Non-library errors */ + const char *const *addon_message_table; + + /* code for first string in addon table */ + int first_addon_message; + + /* code for last string in addon table */ + int last_addon_message; +}; + + +/* + Progress monitor object +*/ + +struct jpeg_progress_mgr { + void ( *progress_monitor ) ( j_common_ptr cinfo ); + + /* work units completed in this pass */ + long pass_counter; + + /* total number of work units in this pass */ + long pass_limit; + + /* passes completed so far */ + int completed_passes; + + /* total number of passes expected */ + int total_passes; +}; + + +/* + Data destination object for compression +*/ + +struct jpeg_destination_mgr { + /* => next byte to write in buffer */ + unsigned char *next_output_byte; + + /* # of byte spaces remaining in buffer */ + long unsigned int free_in_buffer; + + void ( *init_destination ) ( j_compress_ptr cinfo ); + int ( *empty_output_buffer ) ( j_compress_ptr cinfo ); + void ( *term_destination ) ( j_compress_ptr cinfo ); +}; + + +/* + Memory manager object. + Allocates "small" objects (a few K total), "large" objects (tens of K), and + "really big" objects (virtual arrays with backing store if needed). The memory + manager does not allow individual objects to be freed; rather, each created + object is assigned to a pool, and whole pools can be freed at once. This is + faster and more convenient than remembering exactly what to free, especially + where malloc()/free() are not too speedy. + NB: alloc routines never return (void*)0. They exit to error_exit if not + successful. +*/ + +typedef struct jvirt_sarray_control *jvirt_sarray_ptr; +typedef struct jvirt_barray_control *jvirt_barray_ptr; + +struct jpeg_memory_mgr { + /* + Method pointers + */ + void *( *alloc_small ) ( + j_common_ptr cinfo, int pool_id, long unsigned int sizeofobject ); + + void *( *alloc_large ) ( + j_common_ptr cinfo, int pool_id, long unsigned int sizeofobject ); + + JSAMPARRAY ( *alloc_sarray ) ( + j_common_ptr cinfo, int pool_id, unsigned int samplesperrow, + unsigned int numrows ); + + JBLOCKARRAY ( *alloc_barray )( + j_common_ptr cinfo, int pool_id, unsigned int blocksperrow, + unsigned int numrows ); + + jvirt_sarray_ptr ( *request_virt_sarray ) ( + j_common_ptr cinfo, int pool_id, int pre_zero, unsigned int samplesperrow, + unsigned int numrows, unsigned int maxaccess ); + + jvirt_barray_ptr ( *request_virt_barray ) ( + j_common_ptr cinfo, int pool_id, int pre_zero, unsigned int blocksperrow, + unsigned int numrows, unsigned int maxaccess ); + + void ( *realize_virt_arrays ) ( j_common_ptr cinfo ); + + JSAMPARRAY ( *access_virt_sarray ) ( + j_common_ptr cinfo, jvirt_sarray_ptr ptr, unsigned int start_row, + unsigned int num_rows, int writable ); + + JBLOCKARRAY ( *access_virt_barray ) ( + j_common_ptr cinfo, jvirt_barray_ptr ptr, unsigned int start_row, + unsigned int num_rows, int writable ); + + void ( *free_pool ) ( j_common_ptr cinfo, int pool_id ); + + void ( *self_destruct ) ( j_common_ptr cinfo ); + + /* + Limit on memory allocation for this JPEG object. (Note that this is merely + advisory, not a guaranteed maximum; it only affects the space used for + virtual-array buffers.) May be changed by outer application after creating + the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + +#endif /* JPEGLIB_H */ diff --git a/baseline/source/cjpeg_wrbmp/ChangeLog.txt b/baseline/source/cjpeg_wrbmp/ChangeLog.txt new file mode 100644 index 0000000..df21770 --- /dev/null +++ b/baseline/source/cjpeg_wrbmp/ChangeLog.txt @@ -0,0 +1,104 @@ +File: cjpeg_jpeg6b_wrbmp.c +Original provenience: + +2017-04-18: +- Annotated cjpeg_wrbmp_main as entry-point for timing analysis + +2015-10-14: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Changed struct name to cjpeg_jpeg6b_wrbmp_name +- Changed the global variable from {name} to cjpeg_jpeg6b_wrbmp_{name} +- Changed the functions from {name} to cjpeg_jpeg6b_wrbmp_{name} +- Removed code in comment +- Added cjpeg_jpeg6b_wrbmp_main() +- Added cjpeg_jpeg6b_wrbmp_return() +- Added cjpeg_jpeg6b_wrbmp_init() +- Added forward declaration of the functions +- Removed unused variables: test_image[] and color_map[] +- Applied Code Style + +File: input.c +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed _jpeg6b_ from the prefix +- Changed the global variable from colormap to cjpeg_jpeg6b_wrbmp_colormap +- Removed unused variables: test_image[] and color_map[] +- Moved initialization of cjpeg_jpeg6b_wrbmp_colormap to function. This function is called from cjpeg_jpeg6b_wrbmp_init function +- Applied Code Style + +File: cderror.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed _jpeg6b_ from the prefix +- Changed JMESSAGE to CJPEG_JPEG6B_WRBMP_JMESSAGE +- Changed JMAKE_ENUM_LIST to CJPEG_JPEG6B_WRBMP_JMAKE_ENUM_LIST +- Applied Code Style + + +File: cdjpeg.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Rename structs and typedef to cjpeg_jpeg6b_wrbmp_{name} +- Removed unused defines + +File: jconfig.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Change defines to CJPEG_JPEG6B_WRBMP_{NAME} +- Removed _jpeg6b_ from the prefix +- Applied Code Style + + +File: jerror.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed error and warning defines +- Removed _jpeg6b_ from the prefix +- Applied Code Style + + +File: jmorecfg.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Added generic TACLeBench header to line 1 +- Removed unused comments +- Removed _jpeg6b_ from the prefix +- Removed unused defines +- Removed unused typedefs +- Applied Code Style + + +File: jpeglib.h +Original provenience: + +2015-10-12: +- Remove comment on line 1 +- Used define value directly +- Remove unused typedefs, defines +- Removed _jpeg6b_ from the prefix +- Changed struct name to cjpeg_jpeg6b_wrbmp_{name} +- Changed define {name} to cjpeg_jpeg6b_wrbmp_{name} +- Added generic TACLeBench header to line 1 +- Applied Code Style + + + + diff --git a/baseline/source/cjpeg_wrbmp/README b/baseline/source/cjpeg_wrbmp/README new file mode 100644 index 0000000..fa69a18 --- /dev/null +++ b/baseline/source/cjpeg_wrbmp/README @@ -0,0 +1,383 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 6a of 7-Feb-96 +================================= + +This distribution contains the sixth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +Serious users of this software (particularly those incorporating it into +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to +our electronic mailing list. Mailing list members are notified of updates +and have a chance to participate in technical discussions, etc. + +This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim +Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi, +Ge' Weijers, and other members of the Independent JPEG Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +RELATED SOFTWARE Other stuff you should get. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.doc How to configure and install the IJG software. + usage.doc Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.doc). + wizard.doc Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.doc How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.doc Overview of the JPEG library's internal structure. + filelist.doc Road map of IJG files. + coderules.doc Coding style rules --- please read if you contribute code. + +Please read at least the files install.doc and usage.doc. Useful information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image compression and +decompression. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. JPEG is intended for compressing +"real-world" scenes; line drawings, cartoons and other non-realistic images +are not its strong suit. JPEG is lossy, meaning that the output image is not +exactly identical to the input image. Hence you must not use JPEG if you +have to have identical output bits. However, on typical photographic images, +very good compression levels can be obtained with no visible change, and +remarkably high compression levels are possible if you can tolerate a +low-quality image. For more details, see the references, or just experiment +with various compression settings. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +For legal reasons, we are not distributing code for the arithmetic-coding +variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting +the hierarchical or lossless processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. We have also included +"jpegtran", a utility for lossless transcoding between different JPEG +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for +inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-1996, Thomas G. Lane. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The configuration script "configure" was produced with GNU Autoconf. It +is copyright by the Free Software Foundation but is freely distributable. + +It appears that the arithmetic coding option of the JPEG spec is covered by +patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot +legally be used without obtaining one or more licenses. For this reason, +support for arithmetic coding has been removed from the free JPEG software. +(Since arithmetic coding provides only a marginal gain over the unpatented +Huffman mode, it is unlikely that very many implementations will support it.) +So far as we are aware, there are no patent restrictions on the remaining +code. + +WARNING: Unisys has begun to enforce their patent on LZW compression against +GIF encoders and decoders. You will need a license from Unisys to use the +included rdgif.c or wrgif.c files in a commercial or shareware application. +At this time, Unisys is not enforcing their patent against freeware, so +distribution of this package remains legal. However, we intend to remove +GIF support from the IJG package as soon as a suitable replacement format +becomes reasonably popular. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." + + +REFERENCES +========== + +We highly recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article +is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and +IEEE, and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood +City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and +example C code for a multitude of compression methods including JPEG. It is +an excellent source if you are comfortable reading C code but don't know much +about data compression in general. The book's JPEG sample code is far from +industrial-strength, but when you are ready to look at a full implementation, +you've got one here... + +The best full description of JPEG is the textbook "JPEG Still Image Data +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. +The book includes the complete text of the ISO JPEG standards (DIS 10918-1 +and draft DIS 10918-2). This is by far the most complete exposition of JPEG +in existence, and we highly recommend it. + +The JPEG standard itself is not available electronically; you must order a +paper copy through ISO or ITU. (Unless you feel a need to own a certified +official copy, we recommend buying the Pennebaker and Mitchell book instead; +it's much cheaper and includes a great deal of useful explanatory material.) +In the USA, copies of the standard may be ordered from ANSI Sales at (212) +642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI +doesn't take credit card orders, but Global does.) It's not cheap: as of +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% +shipping/handling. The standard is divided into two parts, Part 1 being the +actual specification, while Part 2 covers compliance testing methods. Part 1 +is titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. + +Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO +document. Part 3 is undergoing ISO balloting and is expected to be approved +by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T +T.84. IJG currently does not support any Part 3 extensions. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. A copy of the JFIF spec is available from: + Literature Department + C-Cube Microsystems, Inc. + 1778 McCarthy Blvd. + Milpitas, CA 95035 + phone (408) 944-6300, fax (408) 944-6314 +A PostScript version of this document is available at ftp.uu.net, file +graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube +mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" +to the server to obtain the JFIF document; send the message "help" if you have +trouble. + +The TIFF 6.0 file format specification can be obtained by FTP from sgi.com +(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed +copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from sgi.com or +from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of +the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. libtiff is available +from sgi.com:/graphics/tiff/. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is ftp.uu.net (Internet +address 192.48.96.9). The most recent released version can always be found +there in directory graphics/jpeg. This particular version will be archived +as graphics/jpeg/jpegsrc.v6a.tar.gz. If you are on the Internet, you +can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't +have FTP access, UUNET's archives are also available via UUCP; contact +help@uunet.uu.net for information on retrieving files that way. + +Numerous Internet sites maintain copies of the UUNET files. However, only +ftp.uu.net is guaranteed to have the latest official version. + +You can also obtain this software in DOS-compatible "zip" archive format from +the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe +in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools". +Again, these versions may sometimes lag behind the ftp.uu.net release. + +The JPEG FAQ (Frequently Asked Questions) article is a useful source of +general information about JPEG. It is updated constantly and therefore is +not included in this distribution. The FAQ is posted every two weeks to +Usenet newsgroups comp.graphics.misc, news.answers, and other groups. +You can always obtain the latest version from the news.answers archive at +rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and +.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +RELATED SOFTWARE +================ + +Numerous viewing and image manipulation programs now support JPEG. (Quite a +few of them use this library to do so.) The JPEG FAQ described above lists +some of the more popular free and shareware viewers, and tells where to +obtain them on Internet. + +If you are on a Unix machine, we highly recommend Jef Poskanzer's free +PBMPLUS image software, which provides many useful operations on PPM-format +image files. In particular, it can convert PPM images to and from a wide +range of other formats. You can obtain this package by FTP from ftp.x.org +(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also +a newer update of this package called NETPBM, available from +wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/. +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software +is; you are likely to have difficulty making it work on any non-Unix machine. + +A different free JPEG implementation, written by the PVRG group at Stanford, +is available from havefun.stanford.edu in directory pub/jpeg. This program +is designed for research and experimentation rather than production use; +it is slower, harder to use, and less portable than the IJG code, but it +is easier to read and modify. Also, the PVRG code supports lossless JPEG, +which we do not. + + +FILE FORMAT WARS +================ + +Some JPEG programs produce files that are not compatible with our library. +The root of the problem is that the ISO JPEG committee failed to specify a +concrete file format. Some vendors "filled in the blanks" on their own, +creating proprietary formats that no one else could read. (For example, none +of the early commercial JPEG implementations for the Macintosh were able to +exchange compressed files.) + +The file format we have adopted is called JFIF (see REFERENCES). This format +has been agreed to by a number of major commercial JPEG vendors, and it has +become the de facto standard. JFIF is a minimal or "low end" representation. +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF +Technical Note #2) for "high end" applications that need to record a lot of +additional data about an image. TIFF/JPEG is fairly new and not yet widely +supported, unfortunately. + +The upcoming JPEG Part 3 standard defines a file format called SPIFF. +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should +be able to read the most common variant of SPIFF. SPIFF has some technical +advantages over JFIF, but its major claim to fame is simply that it is an +official standard rather than an informal one. At this point it is unclear +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto +standard. IJG intends to support SPIFF once the standard is frozen, but we +have not decided whether it should become our default output format or not. +(In any case, our decoder will remain capable of reading JFIF indefinitely.) + +Various proprietary file formats incorporating JPEG compression also exist. +We have little or no sympathy for the existence of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, open format standards for JPEG files. Don't +use a proprietary file format! + + +TO DO +===== + +In future versions, we are considering supporting some of the upcoming JPEG +Part 3 extensions --- principally, variable quantization and the SPIFF file +format. + +Tuning the software for better behavior at low quality/high compression +settings is also of interest. The current method for scaling the +quantization tables is known not to be very good at low Q values. + +As always, speeding things up is high on our priority list. + +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. diff --git a/baseline/source/cjpeg_wrbmp/cderror.h b/baseline/source/cjpeg_wrbmp/cderror.h new file mode 100644 index 0000000..e479834 --- /dev/null +++ b/baseline/source/cjpeg_wrbmp/cderror.h @@ -0,0 +1,140 @@ + +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: cderror.h + + Author: Thomas G. Lane. + + This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file defines the error and message codes for the cjpeg/djpeg + applications. These strings are not needed as part of the JPEG library + proper. + Edit this file to add new codes, or to translate the message strings to + some other language. + + Source: Independent JPEG Group's software + + Changes: no major functional changes + + License: See the accompanying README file + + */ + +#ifndef CJPEG_WRBMP_JMESSAGE +#ifndef CDERROR_H +#define CDERROR_H +/*First time through, define the enum list*/ +#define CJPEG_WRBMP_JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined*/ +#define CJPEG_WRBMP_JMESSAGE(code,string) +#endif +#endif + +#ifdef CJPEG_WRBMP_JMAKE_ENUM_LIST + +typedef enum { + +#define CJPEG_WRBMP_JMESSAGE(code,string) code , + +#endif + + CJPEG_WRBMP_JMESSAGE( JMSG_FIRSTADDONCODE = 1000, NULL ) //Must be first entry! + + #ifdef CJPEG_WRBMP_BMP_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADCMAP, "Unsupported BMP colormap format" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADHEADER, "Invalid BMP file: bad header length" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported" ) + CJPEG_WRBMP_JMESSAGE( JERR_BMP_NOT, "Not a BMP file - does not start with BM" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP, "%ux%u 24-bit BMP image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image" ) + #endif + + #ifdef CJPEG_WRBMP_GIF_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_GIF_BUG, "GIF output got confused" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_CODESIZE, "Bogus GIF codesize %d" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file" ) + CJPEG_WRBMP_JMESSAGE( JERR_GIF_NOT, "Not a GIF file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF, "%ux%ux%d GIF image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF_BADVERSION, + "Warning: unexpected GIF version number '%c%c%c'" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x" ) + CJPEG_WRBMP_JMESSAGE( JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_BADDATA, "Corrupt data in GIF file" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_ENDCODE, "Premature end of GIF image" ) + CJPEG_WRBMP_JMESSAGE( JWRN_GIF_NOMOREDATA, "Ran out of GIF bits" ) + #endif + + #ifdef CJPEG_WRBMP_PPM_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file" ) + CJPEG_WRBMP_JMESSAGE( JERR_PPM_NOT, "Not a PPM/PGM file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PGM, "%ux%u PGM image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PGM_TEXT, "%ux%u text PGM image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PPM, "%ux%u PPM image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_PPM_TEXT, "%ux%u text PPM image" ) + #endif + + #ifdef RLE_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_RLE_BADERROR, "Bogus error code from RLE library" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_EMPTY, "Empty RLE file" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_EOF, "Premature EOF in RLE header" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_MEM, "Insufficient memory for RLE header" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_NOT, "Not an RLE file" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE" ) + CJPEG_WRBMP_JMESSAGE( JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE, "%ux%u full-color RLE file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_GRAY, "%ux%u grayscale RLE file" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d" ) + CJPEG_WRBMP_JMESSAGE( JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d" ) + #endif + + #ifdef CJPEG_WRBMP_TARGA_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_TGA_BADCMAP, "Unsupported Targa colormap format" ) + CJPEG_WRBMP_JMESSAGE( JERR_TGA_BADPARMS, "Invalid or unsupported Targa file" ) + CJPEG_WRBMP_JMESSAGE( JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB" ) + CJPEG_WRBMP_JMESSAGE( JTRC_TGA, "%ux%u RGB Targa image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_TGA_GRAY, "%ux%u grayscale Targa image" ) + CJPEG_WRBMP_JMESSAGE( JTRC_TGA_MAPPED, "%ux%u colormapped Targa image" ) + #else + CJPEG_WRBMP_JMESSAGE( JERR_TGA_NOTCOMP, "Targa support was not compiled" ) + #endif + + CJPEG_WRBMP_JMESSAGE( JERR_BAD_CMAP_FILE, + "Color map file is invalid or of unsupported format" ) + CJPEG_WRBMP_JMESSAGE( JERR_TOO_MANY_COLORS, + "Output file format cannot handle %d colormap entries" ) + CJPEG_WRBMP_JMESSAGE( JERR_UNGETC_FAILED, "ungetc failed" ) + #ifdef CJPEG_WRBMP_TARGA_SUPPORTED + CJPEG_WRBMP_JMESSAGE( JERR_UNKNOWN_FORMAT, + "Unrecognized input file format --- perhaps you need -targa" ) + #else + CJPEG_WRBMP_JMESSAGE( JERR_UNKNOWN_FORMAT, "Unrecognized input file format" ) + #endif + CJPEG_WRBMP_JMESSAGE( JERR_UNSUPPORTED_FORMAT, "Unsupported output file format" ) + + #ifdef CJPEG_WRBMP_JMAKE_ENUM_LIST + + JMSG_LASTADDONCODE +} CJPEG_WRBMP_ADDON_MESSAGE_CODE; + +#undef CJPEG_WRBMP_JMAKE_ENUM_LIST + #endif + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default*/ +#undef CJPEG_WRBMP_JMESSAGE diff --git a/baseline/source/cjpeg_wrbmp/cdjpeg.h b/baseline/source/cjpeg_wrbmp/cdjpeg.h new file mode 100644 index 0000000..6c3fc7b --- /dev/null +++ b/baseline/source/cjpeg_wrbmp/cdjpeg.h @@ -0,0 +1,105 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: cdjpeg.h + + Author: Thomas G. Lane. + + This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains common declarations for the sample applications + cjpeg and djpeg. It is NOT used by the core JPEG library. + + Source: Independent JPEG Group's software + + Changes: no major functional changes + + License: See the accompanying README file + +*/ +#ifndef CDJPEG_H +#define CDJPEG_H + +#define CJPEG_WRBMP_JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */ +#define CJPEG_WRBMP_JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */ + +#include "jpeglib.h" +#include "jerror.h" /* get library error codes too */ +#include "cderror.h" /* get application-specific error codes */ + +typedef struct cjpeg_wrbmp_cjpeg_source_struct + *cjpeg_wrbmp_cjpeg_source_ptr; + +struct cjpeg_wrbmp_cjpeg_source_struct { + CJPEG_WRBMP_JMETHOD( void, start_input, + ( cjpeg_wrbmp_j_compress_ptr cinfo, + cjpeg_wrbmp_cjpeg_source_ptr sinfo ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JDIMENSION, get_pixel_rows, + ( cjpeg_wrbmp_j_compress_ptr cinfo, + cjpeg_wrbmp_cjpeg_source_ptr sinfo ) ); + CJPEG_WRBMP_JMETHOD( void, finish_input, + ( cjpeg_wrbmp_j_compress_ptr cinfo, + cjpeg_wrbmp_cjpeg_source_ptr sinfo ) ); + + CJPEG_WRBMP_FILE *input_file; + + CJPEG_WRBMP_JSAMPARRAY buffer; + CJPEG_WRBMP_JDIMENSION buffer_height; +}; + + +typedef struct cjpeg_wrbmp_djpeg_dest_struct + *cjpeg_wrbmp_djpeg_dest_ptr; + +struct cjpeg_wrbmp_djpeg_dest_struct { + CJPEG_WRBMP_JMETHOD( void, start_output, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, + cjpeg_wrbmp_djpeg_dest_ptr dinfo ) ); + /* Emit the specified number of pixel rows from the buffer. */ + CJPEG_WRBMP_JMETHOD( void, put_pixel_rows, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, + cjpeg_wrbmp_djpeg_dest_ptr dinfo, + CJPEG_WRBMP_JDIMENSION rows_supplied ) ); + /* Finish up at the end of the image. */ + CJPEG_WRBMP_JMETHOD( void, finish_output, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, + cjpeg_wrbmp_djpeg_dest_ptr dinfo ) ); + + /* Target file spec; filled in by djpeg.c after object is created. */ + CJPEG_WRBMP_FILE *output_file; + + /* Output pixel-row buffer. Created by module init or start_output. + Width is cinfo->output_width * cinfo->output_components; + height is buffer_height. + */ + CJPEG_WRBMP_JSAMPARRAY buffer; + CJPEG_WRBMP_JDIMENSION buffer_height; +} ; + + + +/* + cjpeg/djpeg may need to perform extra passes to convert to or from + the source/destination file format. The JPEG library does not know + about these passes, but we'd like them to be counted by the progress + monitor. We use an expanded progress monitor object to hold the + additional pass count. +*/ + +struct cjpeg_wrbmp_cdjpeg_progress_mgr { + struct cjpeg_wrbmp_jpeg_progress_mgr + pub; /* fields known to JPEG library */ + int completed_extra_passes; /* extra passes completed */ + int total_extra_passes; /* total extra */ + /* last printed percentage stored here to avoid multiple printouts */ + int percent_done; +}; + +typedef struct cjpeg_wrbmp_cdjpeg_progress_mgr + *cjpeg_wrbmp_cd_progress_ptr; + +#endif + diff --git a/baseline/source/cjpeg_wrbmp/cjpeg_wrbmp.c b/baseline/source/cjpeg_wrbmp/cjpeg_wrbmp.c new file mode 100644 index 0000000..7bef7ab --- /dev/null +++ b/baseline/source/cjpeg_wrbmp/cjpeg_wrbmp.c @@ -0,0 +1,225 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: cjpeg_jpeg6b_wrbmp.c + + Author: Thomas G. Lane. + + Function: This file contains routines to write output images in Microsoft "BMP" + format (MS Windows 3.x and OS/2 1.x flavors). + Either 8-bit colormapped or 24-bit full-color format can be written. + No compression is supported. + + These routines may need modification for non-Unix environments or + specialized applications. As they stand, they assume output to + an ordinary stdio stream. + + Source: Independent JPEG Group's software + + Changes: a brief summary of major functional changes (not formatting) + + License: See the accompanying README file + +*/ + +#include "../extra.h" +#include "cdjpeg.h" + +#ifdef CJPEG_WRBMP_BMP_SUPPORTED + +/* + Declaration of global variables +*/ +typedef struct { + struct cjpeg_wrbmp_djpeg_dest_struct pub; /* public fields */ + cjpeg_wrbmp_boolean is_os2; /* saves the OS2 format request flag */ + cjpeg_wrbmp_jvirt_sarray_ptr + whole_image; /* needed to reverse row order */ + CJPEG_WRBMP_JDIMENSION data_width; /* JSAMPLEs per row */ + CJPEG_WRBMP_JDIMENSION + row_width; /* physical width of one row in the BMP file */ + int pad_bytes; /* number of padding bytes needed per row */ + CJPEG_WRBMP_JDIMENSION + cur_output_row; /* next row# to write to virtual array */ +} cjpeg_wrbmp_bmp_dest_struct; + +typedef cjpeg_wrbmp_bmp_dest_struct *cjpeg_wrbmp_bmp_dest_ptr; +extern unsigned char cjpeg_wrbmp_colormap[3][256]; +unsigned char cjpeg_wrbmp_output_array[6144]; +unsigned char *cjpeg_wrbmp_jpeg_stream /*= cjpeg_jpeg6b_wrbmp_output_array*/; +int cjpeg_wrbmp_checksum; + +struct cjpeg_wrbmp_jpeg_decompress_struct + cjpeg_wrbmp_jpeg_dec_1; +struct cjpeg_wrbmp_jpeg_decompress_struct + cjpeg_wrbmp_jpeg_dec_2; +struct cjpeg_wrbmp_djpeg_dest_struct + cjpeg_wrbmp_djpeg_dest; +cjpeg_wrbmp_bmp_dest_struct cjpeg_wrbmp_bmp_dest; + +/* + Forward declaration of functions +*/ +void cjpeg_wrbmp_initInput( void ); +void cjpeg_wrbmp_finish_output_bmp( cjpeg_wrbmp_j_decompress_ptr cinfo); +void cjpeg_wrbmp_write_colormap( cjpeg_wrbmp_j_decompress_ptr + cinfo, + int map_colors, int map_entry_size, + int cMap ); +int cjpeg_wrbmp_putc_modified( int character ); +void cjpeg_wrbmp_init(); +void cjpeg_wrbmp_main(); +int cjpeg_wrbmp_return(); +//int main(); + +/* + Initialization functions +*/ +void cjpeg_wrbmp_init() +{ + cjpeg_wrbmp_initInput(); + + cjpeg_wrbmp_jpeg_dec_1.progress = 0; + cjpeg_wrbmp_jpeg_dec_1.output_height = 30; + cjpeg_wrbmp_jpeg_dec_1.actual_number_of_colors = 256; + cjpeg_wrbmp_jpeg_dec_1.out_color_components = 2; + + cjpeg_wrbmp_jpeg_dec_2.progress = 0; + cjpeg_wrbmp_jpeg_dec_2.output_height = 30; + cjpeg_wrbmp_jpeg_dec_2.actual_number_of_colors = 256; + cjpeg_wrbmp_jpeg_dec_2.out_color_components = 3; + + cjpeg_wrbmp_jpeg_stream = cjpeg_wrbmp_output_array; + + cjpeg_wrbmp_checksum = 0; +} + +/* + Calculation functions +*/ +int cjpeg_wrbmp_putc_modified( int character ) +{ + *( cjpeg_wrbmp_jpeg_stream ) = character; + + ++cjpeg_wrbmp_jpeg_stream; + + cjpeg_wrbmp_checksum += character; + + return character; +} + +void cjpeg_wrbmp_finish_output_bmp( cjpeg_wrbmp_j_decompress_ptr cinfo ) +{ + CJPEG_WRBMP_JDIMENSION row; + cjpeg_wrbmp_cd_progress_ptr progress = + ( cjpeg_wrbmp_cd_progress_ptr ) cinfo->progress; + + // Write the file body from our virtual array + _Pragma( "loopbound min 30 max 30" ) + for ( row = cinfo->output_height; row > 0; --row ) { + if ( progress != 0 ) { + progress->pub.pass_counter = ( long )( cinfo->output_height - row ); + progress->pub.pass_limit = ( long ) cinfo->output_height; + } + } + + if ( progress != 0 ) + progress->completed_extra_passes++; + } + +void cjpeg_wrbmp_write_colormap( cjpeg_wrbmp_j_decompress_ptr + cinfo, + int map_colors, int map_entry_size, int cMap ) +{ + + int num_colors = cinfo->actual_number_of_colors; + int i; + + if ( cMap != 0 ) { + + if ( cinfo->out_color_components == 3 ) { + // Normal case with RGB colormap + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < num_colors; i++ ) { + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[2][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[1][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[0][i] ) ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } + } else { + // Grayscale colormap (only happens with grayscale quantization) + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < num_colors; i++ ) { + + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[2][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[1][i] ) ); + cjpeg_wrbmp_putc_modified( CJPEG_WRBMP_GETJSAMPLE( + cjpeg_wrbmp_colormap[0][i] ) ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } + } + } else { + // If no colormap, must be grayscale data. Generate a linear "map". + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + cjpeg_wrbmp_putc_modified( i ); + cjpeg_wrbmp_putc_modified( i ); + cjpeg_wrbmp_putc_modified( i ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } + } + + // Pad colormap with zeros to ensure specified number of colormap entries. + _Pragma( "loopbound min 512 max 512" ) + for ( ; i < map_colors; i++ ) { + cjpeg_wrbmp_putc_modified( 0 ); + cjpeg_wrbmp_putc_modified( 0 ); + cjpeg_wrbmp_putc_modified( 0 ); + + if ( map_entry_size == 4 ) + cjpeg_wrbmp_putc_modified( 0 ); + } +} + +void _Pragma( "entrypoint" ) cjpeg_wrbmp_main() +{ + cjpeg_wrbmp_finish_output_bmp( &cjpeg_wrbmp_jpeg_dec_1); + cjpeg_wrbmp_write_colormap( &cjpeg_wrbmp_jpeg_dec_1, 768, 4, 1 ); + + cjpeg_wrbmp_finish_output_bmp( &cjpeg_wrbmp_jpeg_dec_2 ); + cjpeg_wrbmp_write_colormap( &cjpeg_wrbmp_jpeg_dec_2, 768, 4, 1 ); +} + +int cjpeg_wrbmp_return() +{ + return (cjpeg_wrbmp_checksum + (-209330) ) != 0; +} + +int main(int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsCompletecomp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + Any dummy blocks added to complete an MCU are not counted; therefore + these values do not depend on whether a scan is interleaved or not. + */ + CJPEG_WRBMP_JDIMENSION width_in_blocks; + CJPEG_WRBMP_JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + For decompression this is the size of the output from one DCT block, + reflecting any scaling we choose to apply during the IDCT step. + Values of 1,2,4,8 are likely to be supported. Note that different + components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + of samples at the main buffer (preprocessing/compression interface), thus + downsampled_width = ceil(image_width * Hi/Hmax) + and similarly for height. For decompression, IDCT scaling is included, so + downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + CJPEG_WRBMP_JDIMENSION downsampled_width; /* actual width in samples */ + CJPEG_WRBMP_JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + components will be ignored (eg grayscale output from YCbCr image), + we can skip most computations for the unused components. + */ + cjpeg_wrbmp_boolean + component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + See jdinput.c comments about the need for this information. + This field is currently used only for decompression. + */ + CJPEG_WRBMP_JQUANT_TBL *quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void *dct_table; +} cjpeg_wrbmp_jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[4]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} cjpeg_wrbmp_jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct cjpeg_wrbmp_jpeg_marker_struct CJPEG_WRBMP_FAR + *jpeg_saved_marker_ptr; + +struct cjpeg_wrbmp_jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + CJPEG_WRBMP_UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + CJPEG_WRBMP_JOCTET CJPEG_WRBMP_FAR + *data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} CJPEG_WRBMP_J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} CJPEG_WRBMP_J_DCT_METHOD; + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} CJPEG_WRBMP_J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define cjpeg_wrbmp_jpeg_common_fields \ + struct cjpeg_wrbmp_jpeg_error_mgr * err; /* Error handler module */\ + struct cjpeg_wrbmp_jpeg_memory_mgr * mem; /* Memory manager module */\ + struct cjpeg_wrbmp_jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + cjpeg_wrbmp_boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + to receive a pointer to this structure. There are no actual instances of + jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. +*/ +struct cjpeg_wrbmp_jpeg_common_struct { + cjpeg_wrbmp_jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + jpeg_decompress_struct. All three structs must agree on these + initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct cjpeg_wrbmp_jpeg_common_struct + *cjpeg_wrbmp_j_common_ptr; +typedef struct cjpeg_wrbmp_jpeg_compress_struct + *cjpeg_wrbmp_j_compress_ptr; +typedef struct cjpeg_wrbmp_jpeg_decompress_struct + *cjpeg_wrbmp_j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct cjpeg_wrbmp_jpeg_compress_struct { + cjpeg_wrbmp_jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct cjpeg_wrbmp_jpeg_destination_mgr *dest; + + /* Description of source image --- these fields must be filled in by + outer application before starting compression. in_color_space must + be correct before you can even call jpeg_set_defaults(). + */ + + CJPEG_WRBMP_JDIMENSION image_width; /* input image width */ + CJPEG_WRBMP_JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + CJPEG_WRBMP_J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + float input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + initialize everything to reasonable defaults, then changing anything + the application specifically wants to change. That way you won't get + burnt when new parameters are added. Also note that there are several + helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + CJPEG_WRBMP_J_COLOR_SPACE + jpeg_color_space; /* colorspace of JPEG image */ + + cjpeg_wrbmp_jpeg_component_info *comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + CJPEG_WRBMP_JQUANT_TBL *quant_tbl_ptrs[4]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + CJPEG_WRBMP_JHUFF_TBL *dc_huff_tbl_ptrs[4]; + CJPEG_WRBMP_JHUFF_TBL *ac_huff_tbl_ptrs[4]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + CJPEG_WRBMP_UINT8 + arith_dc_L[16]; /* L values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_dc_U[16]; /* U values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_ac_K[16]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const cjpeg_wrbmp_jpeg_scan_info + *scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + sequential JPEG file to be emitted. To create a multi-scan file, + set num_scans and scan_info to point to an array of scan definitions. + */ + + cjpeg_wrbmp_boolean + raw_data_in; /* TRUE=caller supplies downsampled data */ + cjpeg_wrbmp_boolean + arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + cjpeg_wrbmp_boolean + optimize_coding; /* TRUE=optimize entropy encoding parms */ + cjpeg_wrbmp_boolean + CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + CJPEG_WRBMP_J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + restart_interval, or in MCU rows by setting restart_in_rows + (in which case the correct restart_interval will be figured + for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + cjpeg_wrbmp_boolean + write_JFIF_header; /* should a JFIF marker be written? */ + CJPEG_WRBMP_UINT8 + JFIF_major_version; /* What to write for the JFIF version number */ + CJPEG_WRBMP_UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + CJPEG_WRBMP_UINT8 density_unit; /* JFIF code for pixel size units */ + CJPEG_WRBMP_UINT16 X_density; /* Horizontal pixel density */ + CJPEG_WRBMP_UINT16 Y_density; /* Vertical pixel density */ + cjpeg_wrbmp_boolean + write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + jpeg_write_scanlines(). Application may use this to control its + processing loop, e.g., "while (next_scanline < image_height)". + */ + + CJPEG_WRBMP_JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + should not be touched by a surrounding application. + */ + + /* + These fields are computed during compression startup + */ + cjpeg_wrbmp_boolean + progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + CJPEG_WRBMP_JDIMENSION + total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + for fully interleaved scans (whether the JPEG file is interleaved or not). + There are v_samp_factor * DCTSIZE sample rows of each component in an + "iMCU" (interleaved MCU) row. + */ + + /* + These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + cjpeg_wrbmp_jpeg_component_info *cur_comp_info[4]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + CJPEG_WRBMP_JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + CJPEG_WRBMP_JDIMENSION + MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[10]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + cjpeg_wrbmp_jpeg_scan_info + *script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct cjpeg_wrbmp_jpeg_decompress_struct { + cjpeg_wrbmp_jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct cjpeg_wrbmp_jpeg_source_mgr *src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + CJPEG_WRBMP_JDIMENSION + image_width; /* nominal image width (from SOF marker) */ + CJPEG_WRBMP_JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + CJPEG_WRBMP_J_COLOR_SPACE + jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + them to default values. + */ + + CJPEG_WRBMP_J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + float output_gamma; /* image gamma wanted in output */ + + cjpeg_wrbmp_boolean buffered_image; /* TRUE=multiple output passes */ + cjpeg_wrbmp_boolean raw_data_out; /* TRUE=downsampled data wanted */ + + CJPEG_WRBMP_J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + cjpeg_wrbmp_boolean + do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + cjpeg_wrbmp_boolean + do_block_smoothing; /* TRUE=apply interblock smoothing */ + + cjpeg_wrbmp_boolean + quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + CJPEG_WRBMP_J_DITHER_MODE + dither_mode; /* type of color dithering to use */ + cjpeg_wrbmp_boolean + two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + cjpeg_wrbmp_boolean + enable_1pass_quant; /* enable future use of 1-pass quantizer */ + cjpeg_wrbmp_boolean + enable_EXTERNal_quant;/* enable future use of EXTERNal colormap */ + cjpeg_wrbmp_boolean + enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + These fields are computed by jpeg_start_decompress(). + You can also use jpeg_calc_output_dimensions() to determine these values + in advance of calling jpeg_start_decompress(). + */ + + CJPEG_WRBMP_JDIMENSION output_width; /* scaled image width */ + CJPEG_WRBMP_JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + high, space and time will be wasted due to unnecessary data copying. + Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + The application can supply a colormap by setting colormap non-NULL before + calling jpeg_start_decompress; otherwise a colormap is created during + jpeg_start_decompress or jpeg_start_output. + The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + CJPEG_WRBMP_JSAMPARRAY + colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + Application may use this to control its processing loop, e.g., + "while (output_scanline < output_height)". + */ + CJPEG_WRBMP_JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + CJPEG_WRBMP_JDIMENSION + input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + output side. The decompressor will not allow output scan/row number + to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + CJPEG_WRBMP_JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + with which component c's DCT coefficient i (in zigzag order) is known. + It is -1 when no data has yet been received, otherwise it is the point + transform (shift) value for the most recent scan of the coefficient + (thus, 0 at completion of the progression). + This pointer is NULL when reading a non-progressive file. + */ + int ( *coef_bits )[64]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + these fields. Note that the decompressor output side may not use + any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + datastreams when processing abbreviated JPEG datastreams. + */ + + CJPEG_WRBMP_JQUANT_TBL *quant_tbl_ptrs[4]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + CJPEG_WRBMP_JHUFF_TBL *dc_huff_tbl_ptrs[4]; + CJPEG_WRBMP_JHUFF_TBL *ac_huff_tbl_ptrs[4]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + cjpeg_wrbmp_jpeg_component_info *comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + cjpeg_wrbmp_boolean + progressive_mode; /* TRUE if SOFn specifies progressive mode */ + cjpeg_wrbmp_boolean + arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + CJPEG_WRBMP_UINT8 + arith_dc_L[16]; /* L values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_dc_U[16]; /* U values for DC arith-coding tables */ + CJPEG_WRBMP_UINT8 + arith_ac_K[16]; /* Kx values for AC arith-coding tables */ + + unsigned int + restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + the JPEG library. + */ + cjpeg_wrbmp_boolean + saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + CJPEG_WRBMP_UINT8 JFIF_major_version; /* JFIF version number */ + CJPEG_WRBMP_UINT8 JFIF_minor_version; + CJPEG_WRBMP_UINT8 density_unit; /* JFIF code for pixel size units */ + CJPEG_WRBMP_UINT16 X_density; /* Horizontal pixel density */ + CJPEG_WRBMP_UINT16 Y_density; /* Vertical pixel density */ + cjpeg_wrbmp_boolean + saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + CJPEG_WRBMP_UINT8 + Adobe_transform; /* Color transform code from Adobe marker */ + + cjpeg_wrbmp_boolean + CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + library, the uninterpreted contents of any or all APPn and COM markers + can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + should not be touched by a surrounding application. + */ + + /* + These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + CJPEG_WRBMP_JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + in fully interleaved JPEG scans, but are used whether the scan is + interleaved or not. We define an iMCU row as v_samp_factor DCT block + rows of each component. Therefore, the IDCT output contains + v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + CJPEG_WRBMP_JSAMPLE + *sample_range_limit; /* table for fast range-limiting */ + + /* + These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. + Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + cjpeg_wrbmp_jpeg_component_info *cur_comp_info[4]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + CJPEG_WRBMP_JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + CJPEG_WRBMP_JDIMENSION + MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[10]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + It is either zero or the code of a JPEG marker that has been + read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master *master; + struct jpeg_d_main_controller *main; + struct jpeg_d_coef_controller *coef; + struct jpeg_d_post_controller *post; + struct jpeg_input_controller *inputctl; + struct jpeg_marker_reader *marker; + struct jpeg_entropy_decoder *entropy; + struct jpeg_inverse_dct *idct; + struct jpeg_upsampler *upsample; + struct jpeg_color_deconverter *cconvert; + struct jpeg_color_quantizer *cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + directly by the surrounding application. + As with all objects in the JPEG library, these structs only define the + publicly visible methods and state variables of a module. Additional + private fields may exist after the public ones. +*/ + + +/* Error handler object */ + +struct cjpeg_wrbmp_jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + CJPEG_WRBMP_JMETHOD( void, error_exit, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + /* Conditionally emit a trace or warning message */ + CJPEG_WRBMP_JMETHOD( void, emit_message, + ( cjpeg_wrbmp_j_common_ptr cinfo, int msg_level ) ); + /* Routine that actually outputs a trace or error message */ + CJPEG_WRBMP_JMETHOD( void, output_message, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + /* Format a message string for the most recent JPEG error or message */ + CJPEG_WRBMP_JMETHOD( void, format_message, + ( cjpeg_wrbmp_j_common_ptr cinfo, char *buffer ) ); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + CJPEG_WRBMP_JMETHOD( void, reset_error_mgr, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + + /* The message ID code and any parameters are saved here. + A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + /* + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + */ + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + but keep going unless emit_message chooses to abort. emit_message + should count warnings in num_warnings. The surrounding application + can check for bad data by seeing if num_warnings is nonzero at the + end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + An application can change the table pointer to switch to a different + message list (typically, to change the language in which errors are + reported). Some applications may wish to add additional error codes + that will be handled by the JPEG library error mechanism; the second + table pointer is used for this purpose. + + First table includes all errors generated by JPEG library itself. + Error code 0 is reserved for a "no such error string" message. + */ + const char *const *jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + It contains strings numbered first_addon_message..last_addon_message. + */ + const char *const *addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct cjpeg_wrbmp_jpeg_progress_mgr { + CJPEG_WRBMP_JMETHOD( void, progress_monitor, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct cjpeg_wrbmp_jpeg_destination_mgr { + CJPEG_WRBMP_JOCTET + *next_output_byte; /* => next byte to write in buffer */ + cjpeg_wrbmp_size_x + free_in_buffer; /* # of byte spaces remaining in buffer */ + + CJPEG_WRBMP_JMETHOD( void, init_destination, + ( cjpeg_wrbmp_j_compress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, empty_output_buffer, + ( cjpeg_wrbmp_j_compress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( void, term_destination, + ( cjpeg_wrbmp_j_compress_ptr cinfo ) ); +}; + + +/* Data source object for decompression */ + +struct cjpeg_wrbmp_jpeg_source_mgr { + const CJPEG_WRBMP_JOCTET + *next_input_byte; /* => next byte to read from buffer */ + cjpeg_wrbmp_size_x bytes_in_buffer; /* # of bytes remaining in buffer */ + + CJPEG_WRBMP_JMETHOD( void, init_source, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, fill_input_buffer, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( void, skip_input_data, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, long num_bytes ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, resync_to_restart, + ( cjpeg_wrbmp_j_decompress_ptr cinfo, int desired ) ); + CJPEG_WRBMP_JMETHOD( void, term_source, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); +}; + + +/* Memory manager object. + Allocates "small" objects (a few K total), "large" objects (tens of K), + and "really big" objects (virtual arrays with backing store if needed). + The memory manager does not allow individual objects to be freed; rather, + each created object is assigned to a pool, and whole pools can be freed + at once. This is faster and more convenient than remembering exactly what + to free, especially where malloc()/free() are not too speedy. + NB: alloc routines never return NULL. They exit to error_exit if not + successful. +*/ + +typedef struct jvirt_sarray_control *cjpeg_wrbmp_jvirt_sarray_ptr; +typedef struct jvirt_barray_control *cjpeg_wrbmp_jvirt_barray_ptr; + + +struct cjpeg_wrbmp_jpeg_memory_mgr { + /* Method pointers */ + CJPEG_WRBMP_JMETHOD( void *, alloc_small, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + cjpeg_wrbmp_size_x sizeofobject ) ); + CJPEG_WRBMP_JMETHOD( void CJPEG_WRBMP_FAR *, alloc_large, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + cjpeg_wrbmp_size_x sizeofobject ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JSAMPARRAY, alloc_sarray, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + CJPEG_WRBMP_JDIMENSION samplesperrow, + CJPEG_WRBMP_JDIMENSION numrows ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JBLOCKARRAY, alloc_barray, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id, + CJPEG_WRBMP_JDIMENSION blocksperrow, + CJPEG_WRBMP_JDIMENSION numrows ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_jvirt_sarray_ptr, + request_virt_sarray, ( cjpeg_wrbmp_j_common_ptr cinfo, + int pool_id, + cjpeg_wrbmp_boolean pre_zero, + CJPEG_WRBMP_JDIMENSION samplesperrow, + CJPEG_WRBMP_JDIMENSION numrows, + CJPEG_WRBMP_JDIMENSION maxaccess ) ); + CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_jvirt_barray_ptr, + request_virt_barray, ( cjpeg_wrbmp_j_common_ptr cinfo, + int pool_id, + cjpeg_wrbmp_boolean pre_zero, + CJPEG_WRBMP_JDIMENSION blocksperrow, + CJPEG_WRBMP_JDIMENSION numrows, + CJPEG_WRBMP_JDIMENSION maxaccess ) ); + CJPEG_WRBMP_JMETHOD( void, realize_virt_arrays, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JSAMPARRAY, access_virt_sarray, + ( cjpeg_wrbmp_j_common_ptr cinfo, + cjpeg_wrbmp_jvirt_sarray_ptr ptr, + CJPEG_WRBMP_JDIMENSION start_row, + CJPEG_WRBMP_JDIMENSION num_rows, + cjpeg_wrbmp_boolean writable ) ); + CJPEG_WRBMP_JMETHOD( CJPEG_WRBMP_JBLOCKARRAY, access_virt_barray, + ( cjpeg_wrbmp_j_common_ptr cinfo, + cjpeg_wrbmp_jvirt_barray_ptr ptr, + CJPEG_WRBMP_JDIMENSION start_row, + CJPEG_WRBMP_JDIMENSION num_rows, + cjpeg_wrbmp_boolean writable ) ); + CJPEG_WRBMP_JMETHOD( void, free_pool, + ( cjpeg_wrbmp_j_common_ptr cinfo, int pool_id ) ); + CJPEG_WRBMP_JMETHOD( void, self_destruct, + ( cjpeg_wrbmp_j_common_ptr cinfo ) ); + + /* Limit on memory allocation for this JPEG object. (Note that this is + merely advisory, not a guaranteed maximum; it only affects the space + used for virtual-array buffers.) May be changed by outer application + after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + Need not pass marker code since it is stored in cinfo->unread_marker. +*/ +typedef CJPEG_WRBMP_JMETHOD( cjpeg_wrbmp_boolean, + jpeg_marker_parser_method, + ( cjpeg_wrbmp_j_decompress_ptr cinfo ) ); + +/* + The JPEG library modules define JPEG_INTERNALS before including this file. + The internal structure declarations are read only when that is true. + Applications using the library should not include jpegint.h, but may wish + to include jerror.h. +*/ + +#ifdef CJPEG_JPEG6B_WRBMP_JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/baseline/source/dijkstra/ChangeLog.txt b/baseline/source/dijkstra/ChangeLog.txt new file mode 100644 index 0000000..f96350b --- /dev/null +++ b/baseline/source/dijkstra/ChangeLog.txt @@ -0,0 +1,44 @@ +File: dijkstra.c +Original provenience: network section of MiBench + +2015-11-30: +- Replaced "NULL" with "0", remove #include of glibc_common.h +- Removed commented code referring to variable "qKill" +- Made ch, i, iPrev, iNode, iCost and iDist local variables +- Stripped (inconsistently applied) Hungarian notation, replaced + prefix "q" with prefix "queue" for global variables, renamed + "next_in" to "queueNext" and "qNew" to "newItem" +- Initialize queueHead statically (like queueCount and queueNext) +- Prefixed all functions and global variables with "dijkstra_", + renaming "dijkstra" to "dijkstra_find" +- Calculate a checksum in dijkstra_main, return its value in new + function dijkstra_return +- Added (empty) function dijkstra_init and a main function +- Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions +- Added function prototypes +- Applied code formatting with astyle as in the example +- Added general TACLeBench header to beginning of source code + +2016-03-15: +- Return 0 if checksum is as expected, -1 otherwise +- Make all initializations explicit +- Touch input matrix with volatile to rule out optimizations +- Add entrypoint pragma + +2016-06-14: +- Removed cast to make C++ compiler happy + +Files: input.h, input.c +Original provenience: network section of MiBench + +2015-11-30: +- Prefix global variable "AdjMatrix" with "dijkstra_" +- Applied code formatting with astyle as in the example + +File: glibc_common.h +Original provenience: network section of MiBench + +2015-11-30: +- Removed file diff --git a/baseline/source/dijkstra/dijkstra.c b/baseline/source/dijkstra/dijkstra.c new file mode 100644 index 0000000..af86ea6 --- /dev/null +++ b/baseline/source/dijkstra/dijkstra.c @@ -0,0 +1,204 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: dijkstra + + Author: unknown + + Function: dijkstra finds the shortest path between nodes in a graph + + Source: network section of MiBench + + Changes: Made some variables local, compute checksum + + License: GPL + +*/ + +#include "../extra.h" +#include "input.h" + +/* + Definitions of symbolic constants +*/ +#define NONE 9999 +#define OUT_OF_MEMORY -1 +#define QUEUE_SIZE 1000 + +/* + Type declarations +*/ +struct _NODE { + int dist; + int prev; +}; + +struct _QITEM { + int node; + int dist; + int prev; + struct _QITEM *next; +}; + +/* + Global variable definitions +*/ +struct _NODE dijkstra_rgnNodes[NUM_NODES]; + +int dijkstra_queueCount; +int dijkstra_queueNext; +struct _QITEM *dijkstra_queueHead; +struct _QITEM dijkstra_queueItems[QUEUE_SIZE]; + +int dijkstra_checksum = 0; + +/* + Forward declaration of functions +*/ +void dijkstra_init( void ); +int dijkstra_return( void ); +int dijkstra_enqueue( int node, int dist, int prev ); +void dijkstra_dequeue( int *node, int *dist, int *prev ); +int dijkstra_qcount( void ); +int dijkstra_find( int chStart, int chEnd ); +void dijkstra_main( void ); +//int main( void ); + +void dijkstra_init( void ) +{ + int i, k; + volatile int x = 0; + _Pragma( "loopbound min 100 max 100" ) + for ( i = 0; i < NUM_NODES; i++ ) { + _Pragma( "loopbound min 100 max 100" ) + for ( k = 0; k < NUM_NODES; k++ ) { + dijkstra_AdjMatrix[i][k] ^= x; + } + } + + dijkstra_queueCount = 0; + dijkstra_queueNext = 0; + dijkstra_queueHead = ( struct _QITEM * )0; + + dijkstra_checksum = 0; +} + +int dijkstra_return( void ) +{ + return ( ( dijkstra_checksum == 25 ) ? 0 : -1 ); +} + +int dijkstra_enqueue( int node, int dist, int prev ) +{ + struct _QITEM *newItem = &dijkstra_queueItems[dijkstra_queueNext]; + struct _QITEM *last = dijkstra_queueHead; + + if ( ++dijkstra_queueNext >= QUEUE_SIZE ) + return OUT_OF_MEMORY; + newItem->node = node; + newItem->dist = dist; + newItem->prev = prev; + newItem->next = 0; + + if ( !last ) + dijkstra_queueHead = newItem; + else { + /* TODO: where does this magic loop bound come from? */ + _Pragma( "loopbound min 0 max 313" ) + while ( last->next ) + last = last->next; + last->next = newItem; + } + dijkstra_queueCount++; + return 0; +} + +void dijkstra_dequeue( int *node, int *dist, int *prev ) +{ + if ( dijkstra_queueHead ) { + *node = dijkstra_queueHead->node; + *dist = dijkstra_queueHead->dist; + *prev = dijkstra_queueHead->prev; + dijkstra_queueHead = dijkstra_queueHead->next; + dijkstra_queueCount--; + } +} + +int dijkstra_qcount( void ) +{ + return ( dijkstra_queueCount ); +} + +int dijkstra_find( int chStart, int chEnd ) +{ + int ch; + int prev, node; + int cost, dist; + int i; + + _Pragma( "loopbound min 100 max 100" ) + for ( ch = 0; ch < NUM_NODES; ch++ ) { + dijkstra_rgnNodes[ch].dist = NONE; + dijkstra_rgnNodes[ch].prev = NONE; + } + + if ( chStart == chEnd ) { + } else { + dijkstra_rgnNodes[chStart].dist = 0; + dijkstra_rgnNodes[chStart].prev = NONE; + + if ( dijkstra_enqueue ( chStart, 0, NONE ) == OUT_OF_MEMORY ) + return OUT_OF_MEMORY; + + /* TODO: where does this magic loop bound come from? */ + _Pragma( "loopbound min 618 max 928" ) + while ( dijkstra_qcount() > 0 ) { + dijkstra_dequeue ( &node, &dist, &prev ); + _Pragma( "loopbound min 100 max 100" ) + for ( i = 0; i < NUM_NODES; i++ ) { + if ( ( cost = dijkstra_AdjMatrix[node][i] ) != NONE ) { + if ( ( NONE == dijkstra_rgnNodes[i].dist ) || + ( dijkstra_rgnNodes[i].dist > ( cost + dist ) ) ) { + dijkstra_rgnNodes[i].dist = dist + cost; + dijkstra_rgnNodes[i].prev = node; + if ( dijkstra_enqueue ( i, dist + cost, node ) == OUT_OF_MEMORY ) + return OUT_OF_MEMORY; + } + } + } + } + } + return 0; +} + +void _Pragma( "entrypoint" ) dijkstra_main( void ) +{ + int i, j; + + /* finds 20 shortest paths between nodes */ + _Pragma( "loopbound min 20 max 20" ) + for ( i = 0, j = NUM_NODES / 2; i < 20; i++, j++ ) { + j = j % NUM_NODES; + if ( dijkstra_find( i, j ) == OUT_OF_MEMORY ) { + dijkstra_checksum += OUT_OF_MEMORY; + return; + } else + dijkstra_checksum += dijkstra_rgnNodes[j].dist; + dijkstra_queueNext = 0; + } +} + +int main(int argc, char** argv ) +{ + SET_UP + for(jobsComplete=-1; jobsComplete=0 ? x : -(x)) +#define FILTER 0 +#define EXPAND 1 +#define IS == +#define ISNT != +#define AND && +#define OR || + +#define NUM_LEVELS 4 + + +/* + Forward declaration of functions +*/ + +void epic_init( void ); +void epic_build_pyr( float *image, int x_size, int y_size, int num_levels, + float *lo_filter, float *hi_filter, int filter_size ); +void epic_build_level( float *image, int level_x_size, int level_y_size, + float *lo_filter, float *hi_filter, + int filter_size, float *result_block ); +void epic_internal_transpose( float *mat, int rows, int cols ); +void epic_internal_filter( float *image, int x_dim, int y_dim, float *filt, + float *temp, int x_fdim, int y_fdim, + int xgrid_start, int xgrid_step, int ygrid_start, + int ygrid_step, float *result ); +void epic_reflect1( float *filt, int x_dim, int y_dim, int x_pos, int y_pos, + float *result, int f_or_e ); +void epic_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +float epic_filtertemp[FILTER_SIZE]; +float epic_hi_imagetemp[X_SIZE * Y_SIZE / 2]; +float epic_lo_imagetemp[X_SIZE * Y_SIZE / 2]; + +static float epic_lo_filter[FILTER_SIZE] = { + -0.0012475221, -0.0024950907, 0.0087309530, 0.0199579580, + -0.0505290000, -0.1205509700, 0.2930455800, + 0.7061761600, + 0.2930455800, -0.1205509700, -0.0505290000, + 0.0199579580, 0.0087309530, -0.0024950907, -0.0012475221 +}; + +static float epic_hi_filter[FILTER_SIZE] = { + 0.0012475221, -0.0024950907, -0.0087309530, 0.0199579580, + 0.0505290000, -0.1205509700, -0.2930455800, + 0.7061761600, + -0.2930455800, -0.1205509700, 0.0505290000, + 0.0199579580, -0.0087309530, -0.0024950907, 0.0012475221 +}; + + +/* + Initialization function +*/ + +void epic_init( void ) +{ + int i; + + _Pragma( "loopbound min 4096 max 9801" ) + for ( i = 0; i < X_SIZE * Y_SIZE; ++i ) + epic_image[i] *= SCALE_FACTOR; +} + + +/* + Algorithm core functions +*/ + +/* + ====================================================================== + epic_build_pyr() -- builds a separable QMF-style pyramid. The pyramid + is written over the original image. NOTE: the image size must be + divisible by 2^num_levels, but we do not check this here. + ====================================================================== +*/ +void epic_build_pyr( float *image, int x_size, int y_size, int num_levels, + float *lo_filter, float *hi_filter, int filter_size ) +{ + int x_level, y_level, level; + + x_level = x_size; + y_level = y_size; + + _Pragma( "loopbound min 4 max 4" ) + for ( level = 0; level < num_levels; ++level ){ + epic_build_level( image, x_level, y_level, lo_filter, hi_filter, + filter_size, image ); + x_level /= 2; + y_level /= 2; + } +} + + +/* + ====================================================================== + epic_build_level() -- builds a level of the pyramid by computing 4 + filtered and subsampled images. Since the convolution is separable, + image and result-block can point to the same place! Image order is + lowpass, horizontal, vertical (transposed), and diagonal. + ====================================================================== +*/ +void epic_build_level( float *image, int level_x_size, int level_y_size, + float *lo_filter, float *hi_filter, + int filter_size, float *result_block ) +{ + int total_size = level_x_size * level_y_size; + + /* filter and subsample in the X direction */ + epic_internal_filter ( image, level_x_size, level_y_size, + lo_filter, epic_filtertemp, filter_size, 1, + 0, 2, 0, 1, epic_lo_imagetemp ); + epic_internal_filter ( image, level_x_size, level_y_size, + hi_filter, epic_filtertemp, filter_size, 1, + 1, 2, 0, 1, epic_hi_imagetemp ); + + level_x_size /= 2; + /* now filter and subsample in the Y direction */ + epic_internal_filter ( epic_lo_imagetemp, level_x_size, + level_y_size, /* lowpass */ + lo_filter, epic_filtertemp, 1, filter_size, + 0, 1, 0, 2, result_block ); + epic_internal_filter ( epic_lo_imagetemp, level_x_size, + level_y_size, /* horizontal */ + hi_filter, epic_filtertemp, 1, filter_size, + 0, 1, 1, 2, ( result_block += ( total_size / 4 ) ) ); + epic_internal_filter ( epic_hi_imagetemp, level_x_size, + level_y_size, /* vertical */ + lo_filter, epic_filtertemp, 1, filter_size, + 0, 1, 0, 2, ( result_block += ( total_size / 4 ) ) ); + /* transpose the vertical band for more efficient scanning */ + epic_internal_transpose( result_block, level_y_size / 2, level_x_size ); + epic_internal_filter ( epic_hi_imagetemp, level_x_size, + level_y_size, /* diagonal */ + hi_filter, epic_filtertemp, 1, filter_size, + 0, 1, 1, 2, ( result_block += ( total_size / 4 ) ) ); +} + + +/* + ====================================================================== + In-place matrix tranpose algorithm. Handles non-square matrices, + too! Is there a faster algorithm?? + ====================================================================== +*/ +void epic_internal_transpose( float *mat, int rows, int cols ) +{ + register int swap_pos; + register int modulus = rows * cols - 1; + register int current_pos; + register float swap_val; + + /* loop, ignoring first and last elements */ + _Pragma( "loopbound min 1022 max 2399" ) + for ( current_pos = 1; current_pos < modulus; ++current_pos ) { + /* Compute swap position */ + swap_pos = current_pos; + + _Pragma( "loopbound min 1 max 2" ) + do { + swap_pos = ( swap_pos * cols ) % modulus; + } while ( swap_pos < current_pos ); + + if ( current_pos != swap_pos ) { + swap_val = mat[swap_pos]; + mat[swap_pos] = mat[current_pos]; + mat[current_pos] = swap_val; + } + } +} + + +/* -------------------------------------------------------------------- + Correlate FILT with IMAGE, subsampling according to GRID parameters, + with values placed into result array. TEMP is a temporary + array the size of the filter. EDGES is a string -- see convolve.h. + The convolution is done in 9 sections, where the border sections use + specially computed edge-handling filters (see edges.c). The origin + of the filter is assumed to be (floor(x_fdim/2), floor(y_fdim/2)). + 10/6/89 - approximately optimized the choice of register vars on SPARCS. + ------------------------------------------------------------------------ */ +void epic_internal_filter( float *image, int x_dim, int y_dim, float *filt, + float *temp, int x_fdim, int y_fdim, + int xgrid_start, int xgrid_step, int ygrid_start, + int ygrid_step, float *result ) +{ + //register double sum; + register float sum; + register int x_filt, im_pos, y_filt_lin; + register int y_im_lin, x_pos, filt_size = x_fdim * y_fdim; + register int y_pos, res_pos; + register int last_ctr_col = x_dim - x_fdim; + int last_ctr_row = ( y_dim - y_fdim ) * x_dim; + int first_row, first_col ; + int x_fmid = x_fdim / 2; + int y_fmid = y_fdim / 2; + int x_stop = x_fdim - x_fmid + 1; + int y_stop = y_fdim - y_fmid + 1; + int ygrid_step_full = ygrid_step * x_dim; + int prev_res_pos, x_res_dim = ( x_dim - xgrid_start + xgrid_step - 1 ) / + xgrid_step; + int rt_edge_res_pos = x_res_dim; + + res_pos = 0; + first_col = xgrid_start - x_fmid + xgrid_step; + + _Pragma( "loopbound min 1 max 4" ) + for ( y_pos = ygrid_start - y_fmid - 1; y_pos < 0; y_pos += ygrid_step ) { + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos = xgrid_start - x_fmid; /* top-left corner */ + x_pos < 0; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = y_im_lin = 0; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = y_im_lin; + + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + first_col = x_pos + 1; + epic_reflect1( filt, x_fdim, y_fdim, 0, y_pos, temp, FILTER ); + _Pragma( "loopbound min 41 max 46" ) + for ( x_pos = first_col; /* top edge */ + x_pos < last_ctr_col; + x_pos += xgrid_step ) { + sum = 0.0f; + x_filt = y_im_lin = 0; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = x_pos + y_im_lin; + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + rt_edge_res_pos = res_pos + x_res_dim; /* save this for later ... */ + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos += ( 1 - last_ctr_col ); /* top-right corner */ + x_pos < x_stop; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = y_im_lin = 0; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = y_im_lin + last_ctr_col; + + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + } /* end top */ + + first_row = x_dim * ( y_pos + 1 ); /* need this to go down the sides */ + prev_res_pos = res_pos; + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos = xgrid_start - x_fmid; /* left edge */ + x_pos < 1; + x_pos += xgrid_step ) { + res_pos = prev_res_pos; + epic_reflect1( filt, x_fdim, y_fdim, x_pos, 0, temp, FILTER ); + _Pragma( "loopbound min 41 max 97" ) + for ( y_pos = first_row; y_pos < last_ctr_row; + y_pos += ygrid_step_full ) { + sum = 0.0f; + x_filt = 0, y_im_lin = y_pos; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = y_im_lin; + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; x_filt++ ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + res_pos += x_res_dim; + } + prev_res_pos++; + } + epic_reflect1( filt, x_fdim, y_fdim, 0, 0, temp, FILTER ); + _Pragma( "loopbound min 41 max 97" ) + for ( y_pos = first_row; /* center region of image */ + y_pos < last_ctr_row; + y_pos += ygrid_step_full ) { + res_pos = prev_res_pos; + _Pragma( "loopbound min 41 max 46" ) + for ( x_pos = first_col; + x_pos < last_ctr_col; + x_pos += xgrid_step ) { + sum = 0.0f; + x_filt = 0, y_im_lin = y_pos; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + im_pos = x_pos + y_im_lin; + _Pragma( "loopbound min 1 max 15" ) + for ( ; x_filt < y_filt_lin; ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + prev_res_pos += x_res_dim; + } + prev_res_pos = rt_edge_res_pos; + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos += ( 1 - last_ctr_col ); /* right edge */ + x_pos < x_stop; + x_pos += xgrid_step ) { + res_pos = prev_res_pos; + epic_reflect1( filt, x_fdim, y_fdim, x_pos, 0, temp, FILTER ); + _Pragma( "loopbound min 41 max 97" ) + for ( y_pos = first_row; y_pos < last_ctr_row; + y_pos += ygrid_step_full ) { + sum = 0.0f; + x_filt = 0, y_im_lin = y_pos; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; + y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = y_im_lin + last_ctr_col; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + res_pos += x_res_dim; + } + prev_res_pos++; + } /* end mid */ + + res_pos -= ( x_res_dim - 1 ); /* go to lower left corner */ + _Pragma( "loopbound min 1 max 4" ) + for ( y_pos = ( ( y_pos - last_ctr_row ) / x_dim ) + 1; /* bottom */ + y_pos < y_stop; + y_pos += ygrid_step ) { + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos = xgrid_start - x_fmid; /* bottom-left corner */ + x_pos < 1; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = 0, y_im_lin = last_ctr_row; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = y_im_lin; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + epic_reflect1( filt, x_fdim, y_fdim, 0, y_pos, temp, FILTER ); + _Pragma( "loopbound min 41 max 46" ) + for ( x_pos = first_col; /* bottom edge */ + x_pos < last_ctr_col; + x_pos += xgrid_step ) { + sum = 0.0f; + x_filt = 0, y_im_lin = last_ctr_row; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = x_pos + y_im_lin; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + _Pragma( "loopbound min 1 max 4" ) + for ( x_pos += 1 - last_ctr_col; /* bottom-right corner */ + x_pos < x_stop; + x_pos += xgrid_step ) { + epic_reflect1( filt, x_fdim, y_fdim, x_pos, y_pos, temp, FILTER ); + sum = 0.0f; + x_filt = 0, y_im_lin = last_ctr_row; + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt_lin = x_fdim; y_filt_lin <= filt_size; + y_filt_lin += x_fdim ) { + _Pragma( "loopbound min 1 max 15" ) + for ( im_pos = y_im_lin + last_ctr_col; + x_filt < y_filt_lin; + ++x_filt ) { + sum += image[im_pos] * temp[x_filt]; + ++im_pos; + } + y_im_lin += x_dim; + } + result[res_pos] = sum; + ++res_pos; + } + } /* end bottom */ + +} /* end of epic_internal_filter */ + + +/* + The following function determine how edges are to be handled + when performing convolutions of images with linear filters. + Any edge handling function which is local and linear may be defined, + except (unfortunately) constants cannot be added. So to treat the + edges as if the image is surrounded by a gray field, you must paste it + into a gray image, convolve, and crop it out... + The main convolution function is called epic_internal_filter. The idea + is that the convolution function calls the edge handling function which + computes a new filter based on the old filter and the distance to the + edge of the image. For example, reflection is done by reflecting the + filter through the appropriate axis and summing. +*/ + +/* + ---------------- EDGE HANDLER ARGUMENTS ------------------------ + filt - floating point array of filter taps. + x_dim, y_dim - x and y dimensions of filt. + x_pos - position of filter relative to the horizontal image edges. Negative + values indicate left edge, positive indicate right edge. Zero + indicates that the filter is not touching either edge. An absolute + value of 1 indicates that the edge tap of the filter is over the + edge pixel of the image. + y_pos - analogous to x_pos. + result - floating point array where the resulting filter will go. The edge + of this filter will be aligned with the image for application... + f_or_e - equal to one of the two constants EXPAND or FILTER. + -------------------------------------------------------------------- +*/ + +/* -------------------------------------------------------------------- + epic_reflect1() - Reflection through the edge pixels. This is the right + thing to do if you are subsampling by 2, since it maintains parity (even + pixels positions remain even, odd ones remain odd). (note: procedure differs + depending on f_or_e parameter). */ +void epic_reflect1( float *filt, int x_dim, int y_dim, int x_pos, int y_pos, + float *result, int f_or_e ) +{ + int filt_sz = x_dim * y_dim; + register int x_start = 0, y_start = 0, x_stop = x_dim, y_stop = filt_sz; + register int y_filt, x_filt, y_edge, x_edge; + register int x_base = ( x_pos > 0 ) ? ( x_dim - 1 ) : 0; + register int y_base = ( y_pos > 0 ) ? ( x_dim * ( y_dim - 1 ) ) : 0; + int x_edge_dist = ( x_pos > 0 ) ? ( x_pos - x_dim ) : ( ( x_pos < -1 ) ? + ( x_pos + 1 ) : 0 ); + int y_edge_dist = x_dim * ( ( y_pos > 0 ) ? ( y_pos - y_dim ) : ( ( + y_pos < -1 ) ? ( y_pos + 1 ) : 0 ) ); + int i; + int mx_pos = ( x_dim / 2 ) + 1; + int my_pos = ( y_dim / 2 ) + 1; + + _Pragma( "loopbound min 15 max 15" ) + for ( i = 0; i < filt_sz; ++i ) result[i] = 0.0f; + + /* if EXPAND and filter is centered on image edge, do not reflect */ + if ( f_or_e IS EXPAND ) { + if ( x_pos IS mx_pos ) x_stop = ( x_dim + 1 ) / 2; + else + if ( x_pos IS - mx_pos ) { + x_start = x_dim / 2; + x_edge_dist = 0; + } + + if ( y_pos IS my_pos ) y_stop = x_dim * ( ( y_dim + 1 ) / 2 ); + else + if ( y_pos IS - my_pos ) { + y_start = x_dim * ( y_dim / 2 ); + y_edge_dist = 0; + } + } + + y_edge = y_edge_dist; + /* reflect at boundary of image */ + _Pragma( "loopbound min 1 max 15" ) + for ( y_filt = y_start; y_filt < y_stop; y_filt += x_dim ) { + x_edge = x_edge_dist; + _Pragma( "loopbound min 1 max 15" ) + for ( x_filt = y_filt + x_start; x_filt < y_filt + x_stop; ++x_filt ) { + result[abs( y_base - abs( y_edge ) ) + abs( x_base - abs( x_edge ) )] + += filt[x_filt]; + ++x_edge; + } + y_edge += x_dim; + } + + /* if EXPAND and filter is not centered on image edge, mult edge by 2 */ + if ( f_or_e IS EXPAND ) { + if ( ( abs( x_pos ) ISNT mx_pos ) AND ( x_pos ISNT 0 ) ) + _Pragma( "loopbound min 0 max 0" ) + for ( y_filt = x_base; y_filt < filt_sz; y_filt += x_dim ) + result[y_filt] += result[y_filt]; + if ( ( abs( y_pos ) ISNT my_pos ) AND ( y_pos ISNT 0 ) ) + _Pragma( "loopbound min 0 max 0" ) + for ( x_filt = y_base; x_filt < y_base + x_dim; ++x_filt ) + result[x_filt] += result[x_filt]; + } +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) epic_main( void ) +{ + epic_build_pyr( epic_image, X_SIZE, Y_SIZE, NUM_LEVELS, epic_lo_filter, + epic_hi_filter, FILTER_SIZE ); +} + +int epic_return(){ + int i; + int checksum = 0; + for ( i=0 ; i +#include +#include +#include +#include +#include +#include + +#define L3_CACHE_SIZE (11264*1024) + + + +#define SET_UP char *thisProgram=argv[1];\ + int maxJobs=atoi(argv[2]);\ + char *thisCore=argv[3];\ + char *otherCore=argv[4];\ + char *otherProgram=argv[5];\ + char *runID=argv[6];\ + int output=atoi(argv[7]);\ + pid_t killMe;\ + struct timespec start, end;\ + int jobsComplete;\ + long progTime[maxJobs*output];\ + char fileName[50];\ + char *bigArray;\ + int wasteCount;\ + strcpy(fileName, runID);\ + strcat(fileName, ".txt");\ + mlockall(MCL_CURRENT || MCL_FUTURE); + + +//if output==0, endless loop +//avoids int overflow error with large numbers for background loops + +#define SAVE_RESULTS if(jobsComplete>-1) progTime[jobsComplete]=(end.tv_nsec-start.tv_nsec)+(1000000000*(end.tv_sec-start.tv_sec)); + +#define WRITE_TO_FILE if (output){\ + munlockall();\ + FILE *fp=fopen(fileName, "a");\ + if (fp == NULL) {\ + perror("Error opening file. \n");\ + exit(1);\ + }\ + for(jobsComplete=0; jobsComplete +* $Id: fmref.c,v 1.2 2010-10-04 21:21:26 garus Exp $ +*/ + + +#include "../extra.h" +#include "wcclibm.h" +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif + +// Defines +#define SAMPLING_RATE 250000000 +#define CUTOFF_FREQUENCY 108000000 +#define NUM_TAPS 64 +#define MAX_AMPLITUDE 27000.0 +#define BANDWIDTH 10000 +#define DECIMATION 4 +/* Must be at least NUM_TAPS+1: */ +#define IN_BUFFER_LEN 200 +#define EQUALIZER_BANDS 10 + + +// Type declarations +typedef struct FloatBuffer +{ + float buff[IN_BUFFER_LEN]; + int rpos, rlen; +} +FloatBuffer; +/* Low pass filter: */ +typedef struct LPFData +{ + float coeff[NUM_TAPS]; + float freq; + int taps, decimation; +} +LPFData; +typedef struct EqualizerData +{ + LPFData lpf[EQUALIZER_BANDS + 1]; + FloatBuffer fb[EQUALIZER_BANDS + 1]; + float gain[EQUALIZER_BANDS]; +} +EqualizerData; + +// Global vars +float fmref_lpf_coeff[NUM_TAPS]; +float fmref_eq_cutoffs[EQUALIZER_BANDS + 1] = + { 55.000004f, 77.78174f, 110.00001f, 155.56354f, 220.00002f, 311.12695f, + 440.00003f, 622.25415f, 880.00006f, 1244.5078f, 1760.0001f }; +static int fmref_numiters = 2; + +// Forward declarations +void fmref_fb_compact(FloatBuffer *fb); +int fmref_fb_ensure_writable(FloatBuffer *fb, int amount); +void fmref_get_floats(FloatBuffer *fb); +void fmref_init_lpf_data(LPFData *data, float freq, int taps, int decimation); +void fmref_run_lpf(FloatBuffer *fbin, FloatBuffer *fbout, LPFData *data); +void fmref_run_demod(FloatBuffer *fbin, FloatBuffer *fbout); +void fmref_init_equalizer(EqualizerData *data); +void fmref_run_equalizer(FloatBuffer *fbin, FloatBuffer *fbout, EqualizerData *data); +void fmref_main(void); + +void fmref_init(void) +{ + // dummy init function +} + +int fmref_return(void) +{ + // dummy return value + return 0; +} + +int main(int argc, char **argv){ + + SET_UP + for(jobsComplete=-1; jobsComplete 0) { + /* The low-pass filter will need NUM_TAPS+1 items; read them if we + * need to. */ + if (fmref_fb1.rlen - fmref_fb1.rpos < NUM_TAPS + 1) + fmref_get_floats(&fmref_fb1); + fmref_run_lpf(&fmref_fb1, &fmref_fb2, &fmref_lpf_data); + fmref_run_demod(&fmref_fb2, &fmref_fb3); + fmref_run_equalizer(&fmref_fb3, &fmref_fb4, &eq_data); + + } +} + +void fmref_fb_compact(FloatBuffer *fb) +{ + + int i; + char *source; + char *target; + target = (char*)(fb->buff); + source = (char*)(fb->buff + fb->rpos); + _Pragma( "loopbound min 0 max 60" ) + for (i = 0; i < fb->rlen - fb->rpos; i++) { + target[i] = source[i]; + } + fb->rlen -= fb->rpos; + fb->rpos = 0; +} + +int fmref_fb_ensure_writable(FloatBuffer *fb, int amount) +{ + int available = IN_BUFFER_LEN - fb->rlen; + if (available >= amount) + return 1; + + /* Nope, not enough room, move current contents back to the beginning. */ + fmref_fb_compact(fb); + + available = IN_BUFFER_LEN - fb->rlen; + if (available >= amount) + return 1; + + return 0; +} + +void fmref_get_floats(FloatBuffer *fb) +{ + static int x = 0; + fmref_fb_compact(fb); + + /* Fill the remaining space in fb with 1.0. */ + _Pragma( "loopbound min 200 max 200" ) + while (fb->rlen < IN_BUFFER_LEN) { + fb->buff[fb->rlen++] = (float)x; + x++; + } +} + +void fmref_init_lpf_data(LPFData *data, float freq, int taps, int decimation) +{ + /* Assume that CUTOFF_FREQUENCY is non-zero. See comments in + * StreamIt LowPassFilter.java for origin. */ + float w = 2 * M_PI * freq / SAMPLING_RATE; + int i; + float m = taps - 1.0f; + + data->freq = freq; + data->taps = taps; + data->decimation = decimation; + + _Pragma( "loopbound min 64 max 64" ) + for (i = 0; i < taps; i++) { + if (i - m / 2 == 0.0f) + data->coeff[i] = w / M_PI; + else + data->coeff[i] = sin(w * (i - m / 2)) / M_PI / (i - m / 2) * + (0.54f - 0.46f * cos(2 * M_PI * i / m)); + } +} + +void fmref_run_lpf(FloatBuffer *fbin, FloatBuffer *fbout, LPFData *data) +{ + float sum = 0.0f; + int i = 0; + + _Pragma( "loopbound min 64 max 64" ) + for (i = 0; i < data->taps; i++) { + sum += fbin->buff[fbin->rpos + i] * data->coeff[i]; + } + + fbin->rpos += data->decimation + 1; + + /* Check that there's room in the output buffer; move data if necessary. */ + fmref_fb_ensure_writable(fbout, 1); + fbout->buff[fbout->rlen++] = sum; +} + +void fmref_run_demod(FloatBuffer *fbin, FloatBuffer *fbout) +{ + float temp, gain; + gain = MAX_AMPLITUDE * SAMPLING_RATE / (BANDWIDTH * M_PI); + temp = fbin->buff[fbin->rpos] * fbin->buff[fbin->rpos + 1]; + temp = gain * atan(temp); + fbin->rpos++; + fmref_fb_ensure_writable(fbout, 1); + fbout->buff[fbout->rlen++] = temp; +} + +void fmref_init_equalizer(EqualizerData *data) +{ + int i; + + /* Equalizer structure: there are ten band-pass filters, with + * cutoffs as shown below. The outputs of these filters get added + * together. Each band-pass filter is LPF(high)-LPF(low). */ + _Pragma( "loopbound min 11 max 11" ) + for (i = 0; i < EQUALIZER_BANDS + 1; i++) + fmref_init_lpf_data(&data->lpf[i], fmref_eq_cutoffs[i], 64, 0); + + /* Also initialize member buffers. */ + _Pragma( "loopbound min 11 max 11" ) + for (i = 0; i < EQUALIZER_BANDS + 1; i++) + data->fb[i].rpos = data->fb[i].rlen = 0; + + _Pragma( "loopbound min 10 max 10" ) + for (i = 0; i < EQUALIZER_BANDS; i++) { + // the gain amplifies the middle bands the most + float val = (((float)i) - (((float)(EQUALIZER_BANDS - 1)) / 2.0f)) / 5.0f; + data->gain[i] = val > 0 ? 2.0f - val : 2.0f + val; + } +} + +void fmref_run_equalizer(FloatBuffer *fbin, FloatBuffer *fbout, EqualizerData *data) +{ + int i, rpos; + float lpf_out[EQUALIZER_BANDS + 1]; + float sum = 0.0; + + /* Save the input read location; we can reuse the same input data on all + * of the LPFs. */ + rpos = fbin->rpos; + + /* Run the child filters. */ + _Pragma( "loopbound min 11 max 11" ) + for (i = 0; i < EQUALIZER_BANDS + 1; i++) { + fbin->rpos = rpos; + fmref_run_lpf(fbin, &data->fb[i], &data->lpf[i]); + lpf_out[i] = data->fb[i].buff[data->fb[i].rpos++]; + } + + /* Now process the results of the filters. Remember that each band is + * output(hi)-output(lo). */ + _Pragma( "loopbound min 10 max 10" ) + for (i = 0; i < EQUALIZER_BANDS; i++) + sum += (lpf_out[i + 1] - lpf_out[i]) * data->gain[i]; + + /* Write that result. */ + fmref_fb_ensure_writable(fbout, 1); + fbout->buff[fbout->rlen++] = sum; +} + diff --git a/baseline/source/fmref/license.txt b/baseline/source/fmref/license.txt new file mode 100644 index 0000000..7029925 --- /dev/null +++ b/baseline/source/fmref/license.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/baseline/source/fmref/math_private.h b/baseline/source/fmref/math_private.h new file mode 100644 index 0000000..58d4354 --- /dev/null +++ b/baseline/source/fmref/math_private.h @@ -0,0 +1,178 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + */ + +#ifndef _MATH_PRIVATE_H_ +#define _MATH_PRIVATE_H_ + +#include "wcclibm.h" + +//#include +//#include + +/* A representation of a double as a union. */ +union ieee754_double +{ + double d; + + /* This is the IEEE 754 double-precision format. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + } ieee_nan; +}; + +/* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +/* #if __FLOAT_WORD_ORDER == BIG_ENDIAN */ +/* #warning USING Big Endian float word order */ +/* typedef union */ +/* { */ +/* double value; */ +/* struct */ +/* { */ +/* u_int16_t msw; */ +/* u_int16_t lsw; */ +/* } parts; */ +/* } ieeeDoubleShapeType; */ + +/* #endif */ + +/* #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN */ +/* #warning USING Little Endian float word order */ + +typedef union +{ + double value; + struct + { + u_int16_t lsw; + u_int16_t msw; + } parts; +} ieeeDoubleShapeType; + +/* #endif */ + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +{ \ + ieeeDoubleShapeType ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +{ \ + ieeeDoubleShapeType iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + u_int32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +{ \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +{ \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} + + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/baseline/source/fmref/wcclibm.c b/baseline/source/fmref/wcclibm.c new file mode 100644 index 0000000..39b8cbe --- /dev/null +++ b/baseline/source/fmref/wcclibm.c @@ -0,0 +1,522 @@ +#include "math_private.h" +#include "wcclibm.h" + + + +/* e_rem_pio2f.c -- float version of e_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_rem_pio2f.c,v 1.5 1995/05/10 20:46:03 jtc Exp $"; +#endif + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2f() + */ + +/* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ +#ifdef __STDC__ +static const int32_t fmref_npio2_hw[] = { +#else +static int32_t fmref_npio2_hw[] = { +#endif +0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, +0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, +0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, +0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, +0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, +0x4242c700, 0x42490f00 +}; + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const float +#else +static float +#endif +/* zero = 0.0000000000e+00f, /\* 0x00000000 *\/ */ +/* half = 5.0000000000e-01f, /\* 0x3f000000 *\/ */ +/* two8 = 2.5600000000e+02f, /\* 0x43800000 *\/ */ +fmref_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ +fmref_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ +fmref_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ +fmref_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ +fmref_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ +fmref_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ +fmref_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + +#ifdef __STDC__ + int32_t fmref___ieee754_rem_pio2f(float x, float *y) +#else + int32_t fmref___ieee754_rem_pio2f(x,y) + float x,y[]; +#endif +{ + float z,w,t,r,fn; + int32_t i,j,n,ix,hx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - fmref_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - fmref_pio2_1t; + y[1] = (z-y[0])-fmref_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= fmref_pio2_2; + y[0] = z - fmref_pio2_2t; + y[1] = (z-y[0])-fmref_pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + fmref_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + fmref_pio2_1t; + y[1] = (z-y[0])+fmref_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += fmref_pio2_2; + y[0] = z + fmref_pio2_2t; + y[1] = (z-y[0])+fmref_pio2_2t; + } + return -1; + } + } + if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (int32_t) (t*fmref_invpio2+fmref_half); + fn = (float)n; + r = t-fn*fmref_pio2_1; + w = fn*fmref_pio2_1t; /* 1st round good to 40 bit */ + if(n<32&&(int32_t)(ix&0xffffff00)!=fmref_npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix>>23; + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*fmref_pio2_2; + r = t-w; + w = fn*fmref_pio2_2t-((t-r)-w); + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*fmref_pio2_3; + r = t-w; + w = fn*fmref_pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7f800000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + + y[0]=y[1]=x-x; /* dummy initialization */ + return 0; /* doesn't happen for our input */ +} + +/* k_cosf.c -- float version of k_cos.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_cosf.c,v 1.4 1995/05/10 20:46:23 jtc Exp $"; +#endif + + +#ifdef __STDC__ +static const float +#else +static float +#endif +/* one = 1.0000000000e+00, /\* 0x3f800000 *\/ */ +fmref_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ +fmref_C2 = -1.3888889225e-03f, /* 0xbab60b61 */ +fmref_C3 = 2.4801587642e-05f, /* 0x37d00d01 */ +fmref_C4 = -2.7557314297e-07f, /* 0xb493f27c */ +fmref_C5 = 2.0875723372e-09f, /* 0x310f74f6 */ +fmref_C6 = -1.1359647598e-11f; /* 0xad47d74e */ + +#ifdef __STDC__ + float fmref___kernel_cosf(float x, float y) +#else + float fmref___kernel_cosf(x, y) + float x,y; +#endif +{ + float a,hz,z,r,qx; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x32000000) { /* if x < 2**27 */ + if(((int)x)==0) return fmref_one; /* generate inexact */ + } + z = x*x; + r = z*(fmref_C1+z*(fmref_C2+z*(fmref_C3+z*(fmref_C4+z*(fmref_C5+z*fmref_C6))))); + if(ix < 0x3e99999a) /* if |x| < 0.3 */ + return fmref_one - ((float)0.5f*z - (z*r - x*y)); + else { + if(ix > 0x3f480000) { /* x > 0.78125 */ + qx = (float)0.28125f; + } else { + SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ + } + hz = (float)0.5f*z-qx; + a = fmref_one-qx; + return a - (hz - (z*r-x*y)); + } +} + +/* k_sinf.c -- float version of k_sin.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4 1995/05/10 20:46:33 jtc Exp $"; +#endif + + +#ifdef __STDC__ +static const float +#else +static float +#endif +/* half = 5.0000000000e-01f,/\* 0x3f000000 *\/ */ +fmref_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ +fmref_S2 = 8.3333337680e-03f, /* 0x3c088889 */ +fmref_S3 = -1.9841270114e-04f, /* 0xb9500d01 */ +fmref_S4 = 2.7557314297e-06f, /* 0x3638ef1b */ +fmref_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ +fmref_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ + +#ifdef __STDC__ + float fmref___kernel_sinf(float x, float y, int iy) +#else + float fmref___kernel_sinf(x, y, iy) + float x,y; int iy; /* iy=0 if y is zero */ +#endif +{ + float z,r,v; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x32000000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = fmref_S2+z*(fmref_S3+z*(fmref_S4+z*(fmref_S5+z*fmref_S6))); + if(iy==0) return x+v*(fmref_S1+z*r); + else return x-((z*(fmref_half*y-v*r)-y)-v*fmref_S1); +} +/* s_atanf.c -- float version of s_atan.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_atanf.c,v 1.4 1995/05/10 20:46:47 jtc Exp $"; +#endif + + +#ifdef __STDC__ +static const float fmref_atanhi[] = { +#else +static float fmref_atanhi[] = { +#endif + 4.6364760399e-01f, /* atan(0.5)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ +}; + +#ifdef __STDC__ +static const float fmref_atanlo[] = { +#else +static float fmref_atanlo[] = { +#endif + 5.0121582440e-09f, /* atan(0.5)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ +}; + +#ifdef __STDC__ +static const float fmref_aT[] = { +#else +static float fmref_aT[] = { +#endif + 3.3333334327e-01f, /* 0x3eaaaaaa */ + -2.0000000298e-01f, /* 0xbe4ccccd */ + 1.4285714924e-01f, /* 0x3e124925 */ + -1.1111110449e-01f, /* 0xbde38e38 */ + 9.0908870101e-02f, /* 0x3dba2e6e */ + -7.6918758452e-02f, /* 0xbd9d8795 */ + 6.6610731184e-02f, /* 0x3d886b35 */ + -5.8335702866e-02f, /* 0xbd6ef16b */ + 4.9768779427e-02f, /* 0x3d4bda59 */ + -3.6531571299e-02f, /* 0xbd15a221 */ + 1.6285819933e-02f, /* 0x3c8569d7 */ +}; + +/* #ifdef __STDC__ */ +/* static const float */ +/* #else */ +/* static float */ +/* #endif */ +/* one = 1.0, */ +/* huge = 1.0e30; */ + +#ifdef __STDC__ + float fmref___atanf(float x) +#else + float fmref___atanf(x) + float x; +#endif +{ + float w,s1,s2,z; + int32_t ix,hx,id; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x50800000) { /* if |x| >= 2^34 */ + if(ix>0x7f800000) + return x+x; /* NaN */ + if(hx>0) return fmref_atanhi[3]+fmref_atanlo[3]; + else return -fmref_atanhi[3]-fmref_atanlo[3]; + } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ + if (ix < 0x31000000) { /* |x| < 2^-29 */ + if(fmref_huge+x>fmref_one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsf(x); + if (ix < 0x3f980000) { /* |x| < 1.1875 */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = ((float)2.0f*x-fmref_one)/((float)2.0f+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-fmref_one)/(x+fmref_one); + } + } else { + if (ix < 0x401c0000) { /* |x| < 2.4375 */ + id = 2; x = (x-(float)1.5f)/(fmref_one+(float)1.5f*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -(float)1.0f/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(fmref_aT[0]+w*(fmref_aT[2]+w*(fmref_aT[4]+w*(fmref_aT[6]+w*(fmref_aT[8]+w*fmref_aT[10]))))); + s2 = w*(fmref_aT[1]+w*(fmref_aT[3]+w*(fmref_aT[5]+w*(fmref_aT[7]+w*fmref_aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = fmref_atanhi[id] - ((x*(s1+s2) - fmref_atanlo[id]) - x); + return (hx<0)? -z:z; + } +} +//weak_alias (__atanf, atanf) + +/* s_cosf.c -- float version of s_cos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* #ifdef __STDC__ */ +/* static const float one=1.0; */ +/* #else */ +/* static float one=1.0; */ +/* #endif */ + +#ifdef __STDC__ + float fmref___cosf(float x) +#else + float fmref___cosf(x) + float x; +#endif +{ + float y[2],z=0.0f; + int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return fmref___kernel_cosf(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = fmref___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return fmref___kernel_cosf(y[0],y[1]); + case 1: return -fmref___kernel_sinf(y[0],y[1],1); + case 2: return -fmref___kernel_cosf(y[0],y[1]); + default: + return fmref___kernel_sinf(y[0],y[1],1); + } + } +} + +/* s_sinf.c -- float version of s_sin.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + #ifdef __STDC__ + float fmref___sinf(float x) +#else + float fmref___sinf(x) + float x; +#endif +{ + float y[2],z=0.0; + int32_t n, ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return fmref___kernel_sinf(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = fmref___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return fmref___kernel_sinf(y[0],y[1],1); + case 1: return fmref___kernel_cosf(y[0],y[1]); + case 2: return -fmref___kernel_sinf(y[0],y[1],1); + default: + return -fmref___kernel_cosf(y[0],y[1]); + } + } +} + +/* s_fabsf.c -- float version of s_fabs.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabsf(x) returns the absolute value of x. + */ + + +#ifdef __STDC__ + float fmref___fabsf(float x) +#else + float fmref___fabsf(x) + float x; +#endif +{ + u_int32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} diff --git a/baseline/source/fmref/wcclibm.h b/baseline/source/fmref/wcclibm.h new file mode 100644 index 0000000..c00738b --- /dev/null +++ b/baseline/source/fmref/wcclibm.h @@ -0,0 +1,54 @@ +#ifndef _WCCLIBM +#define _WCCLIBM + +#define size_x unsigned long +#define int32_t int +#define uint32_t unsigned int +#define u_int16_t unsigned short +#define u_int32_t unsigned int + +// Often used variables/consts +#ifdef __STDC__ +static const float +#else +static float +#endif +fmref_one = 1.0f, +fmref_half = 5.0000000000e-01f, /* 0x3f000000 */ +fmref_zero = 0.0f, +fmref_huge = 1.0e30, +fmref_two8 = 2.5600000000e+02f, /* 0x43800000 */ +fmref_twon8 = 3.9062500000e-03f; /* 0x3b800000 */ + +// The following defines map the math functions to specialized calls +#define acos fmref___ieee754_acosf +#define atan fmref___atanf +#define cos fmref___cosf +#define fabs fmref___fabsf +#define fabsf fmref___fabsf +#define isinf fmref___isinff +#define pow fmref___ieee754_powf +#define sqrt fmref___ieee754_sqrtf +#define log10 fmref___ieee754_log10f +#define log fmref___ieee754_logf +#define sin fmref___sinf + +float fmref___atanf(float x); +float fmref___copysignf(float x, float y); +float fmref___cosf(float x); +float fmref___fabsf(float x); +float fmref___floorf(float x); +float fmref___ieee754_acosf(float x); +float fmref___ieee754_powf(float x, float y); +int32_t fmref___ieee754_rem_pio2f(float x, float *y); +float fmref___ieee754_sqrtf(float x); +int fmref___isinff (float x); +float fmref___kernel_cosf(float x, float y); +float fmref___kernel_sinf(float x, float y, int iy); +int fmref___kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2); +float fmref___scalbnf (float x, int n); +float fmref___ieee754_logf(float x); +float fmref___ieee754_log10f(float x); +float fmref___sinf(float x); + +#endif // _WCCLIBM diff --git a/baseline/source/g723_enc/ChangeLog.txt b/baseline/source/g723_enc/ChangeLog.txt new file mode 100644 index 0000000..8657026 --- /dev/null +++ b/baseline/source/g723_enc/ChangeLog.txt @@ -0,0 +1,34 @@ +File: g723_enc.c +Original provenience: SUN Microsystems + +2016-03-02: + - Renamed file to g723_enc and removed all g721 dead code + - Added TACLeBench header to line 1 + - Moved SUN license to license.txt + - Deleted unused code that was commented out + - Renamed functions prepended g723_enc to all function names + - Renamed function main to g723_enc_main + - Created new function main, calling g723_enc_init, g723_enc_main and + returning g723_enc_return + - Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions + - Applied code formatting with astyle as in the example + + 2016-03-09: + - Renamed global variables, prepended g723_enc_ + - Removed static keyword from global variables + - Renamed datatype from g723_enc_g72x_state to g723_enc_state + - Renamed function g723_enc_g72x_init_state to g723_enc_init_state + + 2016-05-23: + - Added initialization with volatile int + - Added check_sum and comparison with expected result + +2016-05-25 + - Changed name of struct g723_enc_state to g723_enc_state_t + - Changed name of variable state to g723_enc_state + +2017-07-10 + - Fixed undefined behaviour introduced by accessing the result of a pointer + type cast. diff --git a/baseline/source/g723_enc/g723_enc.c b/baseline/source/g723_enc/g723_enc.c new file mode 100644 index 0000000..6f31210 --- /dev/null +++ b/baseline/source/g723_enc/g723_enc.c @@ -0,0 +1,887 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 1.x + + Name: g723_enc + + Author: Unknown + + Function: g723 encoder. + + Source: SUN Microsystems + + Changes: The benchmark was changed to use the g723 encoder + + License: "Unrestricted use" (see license.txt) + +*/ + +/* + Declaration of data types +*/ + +/* + The following is the definition of the state structure + used by the G.721/G.723 encoder and decoder to preserve their internal + state between successive calls. The meanings of the majority + of the state structure fields are explained in detail in the + CCITT Recommendation G.721. The field names are essentially indentical + to variable names in the bit level description of the coding algorithm + included in this Recommendation. +*/ + +#include "../extra.h" +struct g723_enc_state_t { + long yl; /* Locked or steady state step size multiplier. */ + short yu; /* Unlocked or non-steady state step size multiplier. */ + short dms; /* Short term energy estimate. */ + short dml; /* Long term energy estimate. */ + short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ + + short a[2]; /* Coefficients of pole portion of prediction filter. */ + short b[6]; /* Coefficients of zero portion of prediction filter. */ + short pk[2]; /* + Signs of previous two samples of a partially + reconstructed signal. +*/ + short dq[6]; /* + Previous 6 samples of the quantized difference + signal represented in an internal floating point + format. +*/ + short sr[2]; /* + Previous 2 samples of the quantized difference + signal represented in an internal floating point + format. +*/ + char td; /* delayed tone detect, new in 1988 version */ +}; + + +/* + Forward declaration of functions +*/ + +int g723_enc_abs( int num ); +void g723_enc_init_state( struct g723_enc_state_t *state_ptr ); +int g723_enc_predictor_zero( struct g723_enc_state_t *state_ptr ); +int g723_enc_fmult( int an, int srn ); +int g723_enc_predictor_pole( struct g723_enc_state_t *state_ptr ); +int g723_enc_step_size( struct g723_enc_state_t *state_ptr ); +int g723_enc_quantize( + int d, /* Raw difference signal sample */ + int y, /* Step size multiplier */ + short *table, /* quantization table */ + int size ); /* table size of short integers */ +int g723_enc_reconstruct( + int sign, /* 0 for non-negative value */ + int dqln, /* G.72x codeword */ + int y ); /* Step size multiplier */ +void g723_enc_update( + int code_size, /* distinguish 723_40 with others */ + int y, /* quantizer step size */ + int wi, /* scale factor multiplier */ + int fi, /* for long/short term energies */ + int dq, /* quantized prediction difference */ + int sr, /* reconstructed signal */ + int dqsez, /* difference from 2-pole predictor */ + struct g723_enc_state_t *state_ptr ); /* coder state pointer */ +int g723_enc_quan( + int val, + short *table, + int size ); +int g723_enc_search( + int val, + short *table, + int size ); +int g723_enc_alaw2linear( unsigned char a_val ); +int g723_enc_ulaw2linear( unsigned char u_val ); +int g723_enc_g723_24_encoder( + int sample, + int in_coding, + struct g723_enc_state_t *state_ptr ); +int g723_enc_pack_output( + unsigned char code, + int bits ); + +void g723_enc_init(); +int g723_enc_return(); +void g723_enc_main(); +//int main( void ); + +/* + Declaration of global variables +*/ + +struct g723_enc_state_t g723_enc_state; + +unsigned int g723_enc_INPUT[256] = { + 51, 17, 31, 53, 95, 17, 70, 22, 49, 12, 8, 39, 28, 37, 99, 54, + 77, 65, 77, 78, 83, 15, 63, 31, 35, 92, 52, 40, 61, 79, 94, 87, + 87, 68, 76, 58, 39, 35, 20, 83, 42, 46, 98, 12, 21, 96, 74, 41, + 78, 76, 96, 2, 32, 76, 24, 59, 4, 96, 32, 5, 44, 92, 57, 12, + 57, 25, 50, 23, 48, 41, 88, 43, 36, 38, 4, 16, 52, 70, 9, 40, + 78, 24, 34, 23, 30, 30, 89, 3, 65, 40, 68, 73, 94, 23, 84, 97, + 78, 43, 68, 81, 16, 28, 13, 87, 75, 21, 14, 29, 81, 22, 56, 72, + 19, 99, 25, 43, 76, 86, 90, 98, 39, 43, 12, 46, 24, 99, 65, 61, + 24, 45, 79, 7, 48, 15, 24, 95, 62, 99, 48, 80, 75, 38, 48, 53, + 9, 60, 35, 14, 78, 71, 45, 71, 9, 97, 55, 74, 58, 64, 78, 18, + 30, 28, 69, 29, 57, 42, 30, 44, 57, 49, 61, 42, 13, 25, 3, 98, + 11, 38, 65, 35, 55, 36, 57, 48, 16, 62, 17, 56, 29, 88, 84, 85, + 90, 60, 54, 16, 66, 69, 26, 10, 82, 19, 42, 35, 84, 13, 26, 17, + 48, 38, 50, 50, 35, 53, 12, 52, 61, 74, 56, 34, 80, 59, 26, 67, + 55, 79, 89, 89, 6, 80, 91, 65, 16, 30, 16, 28, 85, 54, 3, 20, + 2, 36, 62, 52, 55, 15, 83, 3, 2, 38, 62, 2, 63, 92, 37, 73 +}; + + + +unsigned int g723_enc_OUTPUT[256]; + +short g723_enc_power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, + 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000 + }; + + +/* + Maps G.723_24 code word to reconstructed scale factor normalized log + magnitude values. +*/ + +short g723_enc_qtab_723_24[3] = {8, 218, 331}; + +/* + Maps G.721 code word to reconstructed scale factor normalized log + magnitude values. +*/ +short g723_enc_dqlntab[16] = { -2048, 4, 135, 213, 273, 323, 373, 425, + 425, 373, 323, 273, 213, 135, 4, -2048 + }; + +/* Maps G.721 code word to log of scale factor multiplier. */ +short g723_enc_witab[16] = { -12, 18, 41, 64, 112, 198, 355, 1122, + 1122, 355, 198, 112, 64, 41, 18, -12 + }; +/* + Maps G.721 code words to a set of values whose long and short + term averages are computed and then compared to give an indication + how stationary (steady state) the signal is. +*/ +short g723_enc_fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, + 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0 + }; + + +/* + Declaration of macros +*/ + + +#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */ +#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */ +#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */ + +#define BIAS (0x84) /* Bias for linear code. */ + +#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ +#define QUANT_MASK (0xf) /* Quantization field mask. */ +#define SEG_SHIFT (4) /* Left shift for segment number. */ +#define SEG_MASK (0x70) /* Segment field mask. */ + +/* + Arithmetic math functions +*/ + +/* + g723_enc_fmult() + + returns the integer product of the 14-bit integer "an" and + "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". +*/ +int g723_enc_fmult( + int an, + int srn ) +{ + short anmag, anexp, anmant; + short wanexp, wanmant; + short retval; + + anmag = ( an > 0 ) ? an : ( ( -an ) & 0x1FFF ); + anexp = g723_enc_quan( anmag, g723_enc_power2, 3 ) - 6; + anmant = ( anmag == 0 ) ? 32 : + ( anexp >= 0 ) ? anmag >> anexp : anmag << -anexp; + wanexp = anexp + ( ( srn >> 6 ) & 0xF ) - 13; + + wanmant = ( anmant * ( srn & 077 ) + 0x30 ) >> 4; + retval = ( wanexp >= 0 ) ? ( ( wanmant << wanexp ) & 0x7FFF ) : + ( wanmant >> -wanexp ); + + return ( ( ( an ^ srn ) < 0 ) ? -retval : retval ); +} + + +/* Manish Verma */ +int g723_enc_abs( int num ) +{ + return ( num < 0 ) ? -num : num; +} + + +/* + Algorithm core functions +*/ + + +/* + g723_enc_quan() + + quantizes the input val against the table of size short integers. + It returns i if table[i - 1] <= val < table[i]. + + Using linear search for simple coding. +*/ +int g723_enc_quan( + int val, + short *table, + int size ) +{ + int i, + j = 0, + k = 1; + + _Pragma( "loopbound min 3 max 15" ) + for ( i = 0; i < size; ++i ) { + + if ( k ) { + if ( val < *table++ ) { + j = i; + k = 0; + } + } + } + + return ( j ); +} + + +/* + g723_enc_predictor_zero() + + computes the estimated signal from 6-zero predictor. + +*/ +int +g723_enc_predictor_zero( + struct g723_enc_state_t *state_ptr ) +{ + int i; + int sezi; + + sezi = g723_enc_fmult( state_ptr->b[0] >> 2, state_ptr->dq[0] ); + _Pragma( "loopbound min 5 max 5" ) + for ( i = 1; i < 6; i++ ) /* ACCUM */ + sezi += g723_enc_fmult( state_ptr->b[i] >> 2, state_ptr->dq[i] ); + + return ( sezi ); +} + + +/* + g723_enc_predictor_pole() + + computes the estimated signal from 2-pole predictor. + +*/ +int +g723_enc_predictor_pole( + struct g723_enc_state_t *state_ptr ) +{ + return ( g723_enc_fmult( state_ptr->a[1] >> 2, state_ptr->sr[1] ) + + g723_enc_fmult( state_ptr->a[0] >> 2, state_ptr->sr[0] ) ); +} + +/* + g723_enc_step_size() + + computes the quantization step size of the adaptive quantizer. + +*/ +int +g723_enc_step_size( + struct g723_enc_state_t *state_ptr ) +{ + int y; + int dif; + int al; + + if ( state_ptr->ap >= 256 ) + return ( state_ptr->yu ); + else { + y = state_ptr->yl >> 6; + dif = state_ptr->yu - y; + al = state_ptr->ap >> 2; + if ( dif > 0 ) + y += ( dif * al ) >> 6; + else + if ( dif < 0 ) + y += ( dif * al + 0x3F ) >> 6; + + return ( y ); + } +} + +/* + g723_enc_quantize() + + Given a raw sample, 'd', of the difference signal and a + quantization step size scale factor, 'y', this routine returns the + ADPCM codeword to which that sample gets quantized. The step + size scale factor division operation is done in the log base 2 domain + as a subtraction. +*/ +int +g723_enc_quantize( + int d, /* Raw difference signal sample */ + int y, /* Step size multiplier */ + short *table, /* quantization table */ + int size ) /* table size of short integers */ +{ + short dqm; /* Magnitude of 'd' */ + short exp; /* Integer part of base 2 log of 'd' */ + short mant; /* Fractional part of base 2 log */ + short dl; /* Log of magnitude of 'd' */ + short dln; /* Step size scale factor normalized log */ + int i; + + /* + LOG + + Compute base 2 log of 'd', and store in 'dl'. + */ + dqm = g723_enc_abs( d ); + exp = g723_enc_quan( dqm >> 1, g723_enc_power2, 15 ); + mant = ( ( dqm << 7 ) >> exp ) & 0x7F; /* Fractional portion. */ + dl = ( exp << 7 ) + mant; + + /* + SUBTB + + "Divide" by step size multiplier. + */ + dln = dl - ( y >> 2 ); + + /* + QUAN + + Obtain codword i for 'd'. + */ + i = g723_enc_quan( dln, table, size ); + + if ( d < 0 ) /* take 1's complement of i */ + return ( ( size << 1 ) + 1 - i ); + else + if ( i == 0 ) /* take 1's complement of 0 */ + return ( ( size << 1 ) + 1 ); /* new in 1988 */ + else + return ( i ); +} +/* + g723_enc_reconstruct() + + Returns reconstructed difference signal 'dq' obtained from + codeword 'i' and quantization step size scale factor 'y'. + Multiplication is performed in log base 2 domain as addition. +*/ +int +g723_enc_reconstruct( + int sign, /* 0 for non-negative value */ + int dqln, /* G.72x codeword */ + int y ) /* Step size multiplier */ +{ + short dql; /* Log of 'dq' magnitude */ + short dex; /* Integer part of log */ + short dqt; + short dq; /* Reconstructed difference signal sample */ + + dql = dqln + ( y >> 2 ); /* ADDA */ + + if ( dql < 0 ) + return ( ( sign ) ? -0x8000 : 0 ); + else { /* ANTILOG */ + dex = ( dql >> 7 ) & 15; + dqt = 128 + ( dql & 127 ); + dq = ( dqt << 7 ) >> ( 14 - dex ); + return ( ( sign ) ? ( dq - 0x8000 ) : dq ); + } +} + + +/* + g723_enc_update() + + updates the state variables for each output code +*/ +void +g723_enc_update( + int code_size, /* distinguish 723_40 with others */ + int y, /* quantizer step size */ + int wi, /* scale factor multiplier */ + int fi, /* for long/short term energies */ + int dq, /* quantized prediction difference */ + int sr, /* reconstructed signal */ + int dqsez, /* difference from 2-pole predictor */ + struct g723_enc_state_t *state_ptr ) /* coder state pointer */ +{ + int cnt; + short mag, exp; /* Adaptive predictor, FLOAT A */ + short a2p; /* LIMC */ + short a1ul; /* UPA1 */ + short pks1; /* UPA2 */ + short fa1; + char tr; /* tone/transition detector */ + short ylint, thr2, dqthr; + short ylfrac, thr1; + short pk0; + + pk0 = ( dqsez < 0 ) ? 1 : 0; /* needed in updating predictor poles */ + + mag = dq & 0x7FFF; /* prediction difference magnitude */ + /* TRANS */ + ylint = state_ptr->yl >> 15; /* exponent part of yl */ + ylfrac = ( state_ptr->yl >> 10 ) & 0x1F; /* fractional part of yl */ + thr1 = ( 32 + ylfrac ) << ylint; /* threshold */ + thr2 = ( ylint > 9 ) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ + dqthr = ( thr2 + ( thr2 >> 1 ) ) >> 1; /* dqthr = 0.75 * thr2 */ + if ( state_ptr->td == 0 ) /* signal supposed voice */ + tr = 0; + else + if ( mag <= dqthr ) /* supposed data, but small mag */ + tr = 0; /* treated as voice */ + else /* signal is data (modem) */ + tr = 1; + + /* + Quantizer scale factor adaptation. + */ + + /* FUNCTW & FILTD & DELAY */ + /* update non-steady state step size multiplier */ + state_ptr->yu = y + ( ( wi - y ) >> 5 ); + + /* LIMB */ + if ( state_ptr->yu < 544 ) /* 544 <= yu <= 5120 */ + state_ptr->yu = 544; + else + if ( state_ptr->yu > 5120 ) + state_ptr->yu = 5120; + + /* FILTE & DELAY */ + /* update steady state step size multiplier */ + state_ptr->yl += state_ptr->yu + ( ( -state_ptr->yl ) >> 6 ); + + /* + Adaptive predictor coefficients. + */ + if ( tr == 1 ) { /* reset a's and b's for modem signal */ + state_ptr->a[0] = 0; + state_ptr->a[1] = 0; + state_ptr->b[0] = 0; + state_ptr->b[1] = 0; + state_ptr->b[2] = 0; + state_ptr->b[3] = 0; + state_ptr->b[4] = 0; + state_ptr->b[5] = 0; + } else { /* update a's and b's */ + pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ + + /* update predictor pole a[1] */ + a2p = state_ptr->a[1] - ( state_ptr->a[1] >> 7 ); + if ( dqsez != 0 ) { + fa1 = ( pks1 ) ? state_ptr->a[0] : -state_ptr->a[0]; + if ( fa1 < -8191 ) /* a2p = function of fa1 */ + a2p -= 0x100; + else + if ( fa1 > 8191 ) + a2p += 0xFF; + else + a2p += fa1 >> 5; + if ( pk0 ^ state_ptr->pk[1] ) + /* LIMC */ + if ( a2p <= -12160 ) + a2p = -12288; + else + if ( a2p >= 12416 ) + a2p = 12288; + else + a2p -= 0x80; + else + if ( a2p <= -12416 ) + a2p = -12288; + else + if ( a2p >= 12160 ) + a2p = 12288; + else + a2p += 0x80; + + } + + /* TRIGB & DELAY */ + state_ptr->a[1] = a2p; + + /* UPA1 */ + /* update predictor pole a[0] */ + state_ptr->a[0] -= state_ptr->a[0] >> 8; + if ( dqsez != 0 ) { + if ( pks1 == 0 ) + state_ptr->a[0] += 192; + else + state_ptr->a[0] -= 192; + } + + /* LIMD */ + a1ul = 15360 - a2p; + if ( state_ptr->a[0] < -a1ul ) + state_ptr->a[0] = -a1ul; + else + if ( state_ptr->a[0] > a1ul ) + state_ptr->a[0] = a1ul; + + /* UPB : update predictor zeros b[6] */ + _Pragma( "loopbound min 6 max 6" ) + for ( cnt = 0; cnt < 6; cnt++ ) { + if ( code_size == 5 ) /* for 40Kbps G.723 */ + state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9; + else /* for G.721 and 24Kbps G.723 */ + state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; + if ( dq & 0x7FFF ) { /* XOR */ + if ( ( dq ^ state_ptr->dq[cnt] ) >= 0 ) + state_ptr->b[cnt] += 128; + else + state_ptr->b[cnt] -= 128; + } + + } + } + + _Pragma( "loopbound min 5 max 5" ) + for ( cnt = 5; cnt > 0; cnt-- ) + state_ptr->dq[cnt] = state_ptr->dq[cnt - 1]; + /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ + if ( mag == 0 ) + state_ptr->dq[0] = ( dq >= 0 ) ? 0x20 : 0xFC20; + else { + exp = g723_enc_quan( mag, g723_enc_power2, 15 ); + state_ptr->dq[0] = ( dq >= 0 ) ? + ( exp << 6 ) + ( ( mag << 6 ) >> exp ) : + ( exp << 6 ) + ( ( mag << 6 ) >> exp ) - 0x400; + + } + + state_ptr->sr[1] = state_ptr->sr[0]; + /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ + if ( sr == 0 ) + state_ptr->sr[0] = 0x20; + else + if ( sr > 0 ) { + exp = g723_enc_quan( sr, g723_enc_power2, 15 ); + state_ptr->sr[0] = ( exp << 6 ) + ( ( sr << 6 ) >> exp ); + } else + if ( sr > -32768 ) { + mag = -sr; + exp = g723_enc_quan( mag, g723_enc_power2, 15 ); + state_ptr->sr[0] = ( exp << 6 ) + ( ( mag << 6 ) >> exp ) - 0x400; + } else + state_ptr->sr[0] = 0xFC20; + + /* DELAY A */ + state_ptr->pk[1] = state_ptr->pk[0]; + state_ptr->pk[0] = pk0; + + /* TONE */ + if ( tr == 1 ) /* this sample has been treated as data */ + state_ptr->td = 0; /* next one will be treated as voice */ + else + if ( a2p < -11776 ) /* small sample-to-sample correlation */ + state_ptr->td = 1; /* signal may be data */ + else /* signal is voice */ + state_ptr->td = 0; + + /* + Adaptation speed control. + */ + state_ptr->dms += ( fi - state_ptr->dms ) >> 5; /* FILTA */ + state_ptr->dml += ( ( ( fi << 2 ) - state_ptr->dml ) >> 7 ); /* FILTB */ + + if ( tr == 1 ) + state_ptr->ap = 256; + else + if ( y < 1536 ) /* SUBTC */ + state_ptr->ap += ( 0x200 - state_ptr->ap ) >> 4; + else + if ( state_ptr->td == 1 ) + state_ptr->ap += ( 0x200 - state_ptr->ap ) >> 4; + else + if ( g723_enc_abs( ( state_ptr->dms << 2 ) - state_ptr->dml ) >= + ( state_ptr->dml >> 3 ) ) + state_ptr->ap += ( 0x200 - state_ptr->ap ) >> 4; + else + state_ptr->ap += ( -state_ptr->ap ) >> 4; + +} + + +/* + g723_enc_alaw2linear() - Convert an A-law value to 16-bit linear PCM + +*/ +int +g723_enc_alaw2linear( + unsigned char a_val ) +{ + int t; + int seg; + + a_val ^= 0x55; + + t = ( a_val & QUANT_MASK ) << 4; + seg = ( ( unsigned )a_val & SEG_MASK ) >> SEG_SHIFT; + switch ( seg ) { + case 0: + t += 8; + break; + case 1: + t += 0x108; + break; + default: + t += 0x108; + t <<= seg - 1; + } + return ( ( a_val & SIGN_BIT ) ? t : -t ); +} + + +/* + g723_enc_ulaw2linear() - Convert a u-law value to 16-bit linear PCM + + First, a biased linear code is derived from the code word. An unbiased + output can then be obtained by subtracting 33 from the biased code. + + Note that this function expects to be passed the complement of the + original code word. This is in keeping with ISDN conventions. +*/ +int +g723_enc_ulaw2linear( + unsigned char u_val ) +{ + int t; + + /* Complement to obtain normal u-law value. */ + u_val = ~u_val; + + /* + Extract and bias the quantization bits. Then + shift up by the segment number and subtract out the bias. + */ + t = ( ( u_val & QUANT_MASK ) << 3 ) + BIAS; + t <<= ( ( unsigned int )u_val & SEG_MASK ) >> SEG_SHIFT; + + return ( ( u_val & SIGN_BIT ) ? ( BIAS - t ) : ( t - BIAS ) ); +} + + +/* + g723_enc_g723_24_encoder() + + Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. + Returns -1 if invalid input coding value. +*/ +int +g723_enc_g723_24_encoder( + int sl, + int in_coding, + struct g723_enc_state_t *state_ptr ) +{ + short sei, sezi, se, sez; /* ACCUM */ + short d; /* SUBTA */ + short y; /* MIX */ + short sr; /* ADDB */ + short dqsez; /* ADDC */ + short dq, i; + + switch ( in_coding ) { /* linearize input sample to 14-bit PCM */ + case AUDIO_ENCODING_ALAW: + sl = g723_enc_alaw2linear( sl ) >> 2; + break; + case AUDIO_ENCODING_ULAW: + sl = g723_enc_ulaw2linear( sl ) >> 2; + break; + case AUDIO_ENCODING_LINEAR: + sl >>= 2; /* sl of 14-bit dynamic range */ + break; + default: + return ( -1 ); + } + + sezi = g723_enc_predictor_zero( state_ptr ); + sez = sezi >> 1; + sei = sezi + g723_enc_predictor_pole( state_ptr ); + se = sei >> 1; /* se = estimated signal */ + + d = sl - se; /* d = estimation diff. */ + + /* quantize prediction difference d */ + y = g723_enc_step_size( state_ptr ); /* quantizer step size */ + i = g723_enc_quantize( d, y, g723_enc_qtab_723_24, 3 ); /* i = ADPCM code */ + dq = g723_enc_reconstruct( i & 4, g723_enc_dqlntab[i], y ); /* quantized diff. */ + + sr = ( dq < 0 ) ? se - ( dq & 0x3FFF ) : se + dq; /* reconstructed signal */ + + dqsez = sr + sez - se; /* pole prediction diff. */ + + g723_enc_update( 3, y, g723_enc_witab[i], g723_enc_fitab[i], dq, sr, dqsez, state_ptr ); + + return ( i ); +} + +/* + Pack output codes into bytes and write them to stdout. + Returns 1 if there is residual output, else returns 0. +*/ +int +g723_enc_pack_output( + unsigned char code, + int bits ) +{ + static unsigned int out_buffer = 0; + static int out_bits = 0; + unsigned char out_byte; + static int i = 0; + + out_buffer |= ( code << out_bits ); + out_bits += bits; + if ( out_bits >= 8 ) { + out_byte = out_buffer & 0xff; + out_bits -= 8; + out_buffer >>= 8; + //fwrite(&out_byte, sizeof (char), 1, fp_out); + //fwrite(&out_byte, 1, 1, fp_out); + g723_enc_OUTPUT[i] = out_byte; + i = i + 1; + } + + return ( out_bits > 0 ); +} + +/* + Initialization- and return-value-related functions +*/ + +/* + g723_enc_init_state() + + This routine initializes and/or resets the g72x_state structure + pointed to by 'state_ptr'. + All the initial state values are specified in the CCITT G.721 document. +*/ +void +g723_enc_init_state( + struct g723_enc_state_t *state_ptr ) +{ + int cnta; + + state_ptr->yl = 34816; + state_ptr->yu = 544; + state_ptr->dms = 0; + state_ptr->dml = 0; + state_ptr->ap = 0; + + _Pragma( "loopbound min 2 max 2" ) + for ( cnta = 0; cnta < 2; cnta++ ) { + state_ptr->a[cnta] = 0; + state_ptr->pk[cnta] = 0; + state_ptr->sr[cnta] = 32; + } + _Pragma( "loopbound min 6 max 6" ) + for ( cnta = 0; cnta < 6; cnta++ ) { + state_ptr->b[cnta] = 0; + state_ptr->dq[cnta] = 32; + } + state_ptr->td = 0; +} + + +void g723_enc_init() +{ + int i; + volatile int x = 0; + g723_enc_init_state( &g723_enc_state ); + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + g723_enc_INPUT[i] += x; + } +} + + +int g723_enc_return() +{ + int i; + int check_sum = 0; + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + check_sum += g723_enc_OUTPUT[i]; + } + + return ( check_sum != 24284 ); +} + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) g723_enc_main() +{ +// struct g72x_state state; + short sample_short; //mv + unsigned char code; + int resid; + int in_coding; + short *in_buf; + int enc_bits; + int i = 0; + + enc_bits = 3; + in_coding = AUDIO_ENCODING_ALAW; + in_buf = &sample_short; + + _Pragma( "loopbound min 256 max 256" ) + for ( i = 0; i < 256; i++ ) { + *in_buf = g723_enc_INPUT[i]; + code = g723_enc_g723_24_encoder( sample_short, in_coding, &g723_enc_state ); + resid = g723_enc_pack_output( code, enc_bits ); + } + + /* Write zero codes until all residual codes are written out */ + _Pragma( "loopbound min 0 max 0" ) + while ( resid ) + resid = g723_enc_pack_output( 0, enc_bits ); +} + + +int main( int argc, char **argv ) +{ + //SET_UP + int jobsComplete; + int maxJobs=9; + for (jobsComplete=-1; jobsComplete= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ + ? MAX_LONGWORD : utmp)) + +/* + # define GSM_ADD(a, b) \ + ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) +*/ +/* Nonportable, but faster: */ + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +#define saturate(x) \ + ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) + +/* Use these if necessary: + + # define GSM_MULT_R(a, b) gsm_mult_r(a, b) + # define GSM_MULT(a, b) gsm_mult(a, b) + # define GSM_L_MULT(a, b) gsm_L_mult(a, b) + + # define GSM_L_ADD(a, b) gsm_L_add(a, b) + # define GSM_ADD(a, b) gsm_add(a, b) + # define GSM_SUB(a, b) gsm_sub(a, b) + + # define GSM_ABS(a) gsm_abs(a) + +*/ + +#endif /* GSM_DEC_ADD_H */ diff --git a/baseline/source/gsm_dec/data.h b/baseline/source/gsm_dec/data.h new file mode 100644 index 0000000..81bf20d --- /dev/null +++ b/baseline/source/gsm_dec/data.h @@ -0,0 +1,865 @@ +#ifndef GSM_DEC_DATA_H +#define GSM_DEC_DATA_H + +gsm_signal gsm_dec_pcmdata[] = { + ( short )0x0000, ( short )0x0000, ( short )0x0010, ( short )0x0010, + ( short )0x0010, ( short )0x0020, ( short )0x0020, ( short )0x0018, + ( short )0x0028, ( short )0x0020, ( short )0x0020, ( short )0x0028, + ( short )0x0028, ( short )0x0020, ( short )0x0030, ( short )0x0030, + ( short )0x0028, ( short )0x0010, ( short )0x0008, ( short )0x0000, + ( short )0x0050, ( short )0x0060, ( short )0x0058, ( short )0x00D0, + ( short )0x00E0, ( short )0x00D0, ( short )0x0118, ( short )0x0128, + ( short )0x0118, ( short )0x0128, ( short )0x0110, ( short )0x0100, + ( short )0x00A0, ( short )0x0058, ( short )0x0048, ( short )0x0058, + ( short )0x0060, ( short )0x0058, ( short )0x0050, ( short )0x0048, + ( short )0x0040, ( short )0x0030, ( short )0x0020, ( short )0x0010, + ( short )0x0008, ( short )0xFFF8, ( short )0xFFE8, ( short )0xFFE0, + ( short )0xFFD8, ( short )0xFFC8, ( short )0xFFC0, ( short )0xFFC0, + ( short )0xFF98, ( short )0xFF78, ( short )0xFF78, ( short )0xFFC8, + ( short )0x0000, ( short )0x0010, ( short )0x0040, ( short )0x0060, + ( short )0x0068, ( short )0x0078, ( short )0x0078, ( short )0x0070, + ( short )0x00A8, ( short )0x00C8, ( short )0x00C8, ( short )0x00E0, + ( short )0x00F0, ( short )0x00E8, ( short )0x00F8, ( short )0x00F8, + ( short )0x00F0, ( short )0x00E0, ( short )0x00C8, ( short )0x00B8, + ( short )0x00E8, ( short )0x0100, ( short )0x00F8, ( short )0x00E8, + ( short )0x00D8, ( short )0x00C0, ( short )0x00A8, ( short )0x0020, + ( short )0xFFC0, ( short )0xFFA0, ( short )0xFFA0, ( short )0xFFA8, + ( short )0xFFB0, ( short )0xFFD0, ( short )0xFFF8, ( short )0x0000, + ( short )0x0020, ( short )0x0030, ( short )0x0030, ( short )0x0030, + ( short )0x0028, ( short )0x0020, ( short )0xFFF0, ( short )0xFFD0, + ( short )0xFFC8, ( short )0xFFC8, ( short )0xFFD0, ( short )0xFFD8, + ( short )0xFFE8, ( short )0xFFF8, ( short )0xFFF8, ( short )0x0008, + ( short )0x0018, ( short )0x0018, ( short )0x0078, ( short )0x00B8, + ( short )0x00C0, ( short )0x0100, ( short )0x0130, ( short )0x0128, + ( short )0x0108, ( short )0x00D8, ( short )0x00C0, ( short )0x0078, + ( short )0x0038, ( short )0x0020, ( short )0x0020, ( short )0x0000, + ( short )0xFFE0, ( short )0xFFE0, ( short )0xFFD8, ( short )0xFFC8, + ( short )0xFFC8, ( short )0xFFA0, ( short )0xFF88, ( short )0xFF98, + ( short )0xFF80, ( short )0xFF70, ( short )0xFF80, ( short )0xFF78, + ( short )0xFF78, ( short )0xFF90, ( short )0xFF80, ( short )0xFF78, + ( short )0xFF78, ( short )0xFF50, ( short )0xFF30, ( short )0xFF50, + ( short )0xFF38, ( short )0xFF30, ( short )0xFF40, ( short )0xFF58, + ( short )0xFF70, ( short )0xFF80, ( short )0xFF50, ( short )0xFF38, + ( short )0xFF40, ( short )0xFF18, ( short )0xFF00, ( short )0xFF08, + ( short )0xFF40, ( short )0xFF68, ( short )0xFF80, ( short )0xFF88, + ( short )0xFF88, ( short )0xFF88, ( short )0xFF88, ( short )0xFFB8, + ( short )0xFFE0, ( short )0xFFF0, ( short )0xFFD0, ( short )0xFFB8, + ( short )0xFFB8, ( short )0xFF90, ( short )0xFF70, ( short )0xFF70, + ( short )0xFF50, ( short )0xFF40, ( short )0xFF40, ( short )0xFF58, + ( short )0xFF70, ( short )0xFF80, ( short )0xFFC8, ( short )0x0000, + ( short )0x0018, ( short )0x0030, ( short )0x0048, ( short )0x0048, + ( short )0x0028, ( short )0x0008, ( short )0xFFF8, ( short )0xFFD8, + ( short )0xFFC8, ( short )0xFFB8, ( short )0xFF98, ( short )0xFF78, + ( short )0xFF70, ( short )0xFFF0, ( short )0x0058, ( short )0x0088, + ( short )0x00B8, ( short )0x00D0, ( short )0x00D8, ( short )0x00E8, + ( short )0x0138, ( short )0x0160, ( short )0x0158, ( short )0x0170, + ( short )0x0178, ( short )0x0160, ( short )0x0168, ( short )0x0160, + ( short )0x0140, ( short )0x0118, ( short )0x00F0, ( short )0x00C8, + ( short )0x0098, ( short )0x0078, ( short )0x0060, ( short )0x0018, + ( short )0xFFC0, ( short )0xFF90, ( short )0xFF48, ( short )0xFF00, + ( short )0xFEE8, ( short )0xFEC8, ( short )0xFEB8, ( short )0xFEB8, + ( short )0xFEA0, ( short )0xFE88, ( short )0xFE80, ( short )0xFEB8, + ( short )0xFEF8, ( short )0xFF38, ( short )0xFFA0, ( short )0xFFE8, + ( short )0x0008, ( short )0x0030, ( short )0x0058, ( short )0x0068, + ( short )0x0068, ( short )0x0070, ( short )0x0068, ( short )0x0050, + ( short )0x0040, ( short )0x0040, ( short )0x0020, ( short )0x0000, + ( short )0xFFE8, ( short )0xFFF0, ( short )0xFFF8, ( short )0xFFF8, + ( short )0x0038, ( short )0x0068, ( short )0x0078, ( short )0x0038, + ( short )0x0008, ( short )0xFFF0, ( short )0xFFE0, ( short )0xFFD8, + ( short )0xFFD8, ( short )0xFFE0, ( short )0xFFD0, ( short )0xFFC8, + ( short )0x0000, ( short )0x0030, ( short )0x0048, ( short )0x0068, + ( short )0x0080, ( short )0x0088, ( short )0x0088, ( short )0x0088, + ( short )0x0088, ( short )0x0088, ( short )0x0088, ( short )0x0078, + ( short )0x0098, ( short )0x00B0, ( short )0x00B8, ( short )0x0098, + ( short )0x0070, ( short )0x0058, ( short )0x0060, ( short )0x0078, + ( short )0x00A8, ( short )0x00B8, ( short )0x00A8, ( short )0x00A0, + ( short )0x0080, ( short )0x0068, ( short )0x0060, ( short )0x0058, + ( short )0x0048, ( short )0x0030, ( short )0x0038, ( short )0x0038, + ( short )0x0030, ( short )0x0050, ( short )0x0058, ( short )0x0060, + ( short )0x0030, ( short )0x0008, ( short )0xFFF8, ( short )0xFF90, + ( short )0xFF48, ( short )0xFF28, ( short )0xFF10, ( short )0xFEF8, + ( short )0xFEF0, ( short )0xFED8, ( short )0xFEB0, ( short )0xFEB0, + ( short )0xFEA8, ( short )0xFEB8, ( short )0xFED8, ( short )0xFEF8, + ( short )0xFF10, ( short )0xFF20, ( short )0xFF40, ( short )0xFF58, + ( short )0xFF80, ( short )0xFFA0, ( short )0xFFB8, ( short )0xFFC8, + ( short )0xFFD8, ( short )0xFFE0, ( short )0xFFF0, ( short )0x0048, + ( short )0x0098, ( short )0x00B0, ( short )0x0068, ( short )0x0018, + ( short )0xFFF8, ( short )0xFFE8, ( short )0xFFF0, ( short )0xFFF8, + ( short )0x0020, ( short )0x0038, ( short )0x0038, ( short )0x0050, + ( short )0x0068, ( short )0x0070, ( short )0x0068, ( short )0x0060, + ( short )0x0060, ( short )0x0038, ( short )0x0020, ( short )0x0018, + ( short )0x0040, ( short )0x0060, ( short )0x0068, ( short )0x0040, + ( short )0x0010, ( short )0x0000, ( short )0xFFB0, ( short )0xFF78, + ( short )0xFF70, ( short )0xFF90, ( short )0xFFA8, ( short )0xFFC8, + ( short )0xFF98, ( short )0xFF50, ( short )0xFF50, ( short )0xFF50, + ( short )0xFF58, ( short )0xFF68, ( short )0xFF48, ( short )0xFF20, + ( short )0xFF18, ( short )0xFF38, ( short )0xFF60, ( short )0xFF70, + ( short )0xFF80, ( short )0xFF98, ( short )0xFFA0, ( short )0xFFB8, + ( short )0xFFD0, ( short )0xFFE0, ( short )0x0018, ( short )0x0048, + ( short )0x0058, ( short )0x00B0, ( short )0x00F8, ( short )0x0108, + ( short )0x0118, ( short )0x0120, ( short )0x0118, ( short )0x0130, + ( short )0x0148, ( short )0x0140, ( short )0x0130, ( short )0x0120, + ( short )0x0108, ( short )0x0098, ( short )0x0038, ( short )0x0018, + ( short )0xFFD0, ( short )0xFF90, ( short )0xFF80, ( short )0xFF58, + ( short )0xFF38, ( short )0xFF30, ( short )0xFF48, ( short )0xFF68, + ( short )0xFF78, ( short )0xFF88, ( short )0xFFB8, ( short )0xFFD8, + ( short )0xFFE8, ( short )0xFFD8, ( short )0xFFF0, ( short )0x0010, + ( short )0x0020, ( short )0x0020, ( short )0x0018, ( short )0x0028, + ( short )0x0030, ( short )0x0030, ( short )0x0038, ( short )0x0060, + ( short )0x0080, ( short )0x0080, ( short )0x00B0, ( short )0x00D8, + ( short )0x00D0, ( short )0x00B8, ( short )0x00A8, ( short )0x00A8, + ( short )0x00A0, ( short )0x0090, ( short )0x0078, ( short )0x0070, + ( short )0x0068, ( short )0x0048, ( short )0x0018, ( short )0x0008, + ( short )0x0008, ( short )0x0000, ( short )0x0000, ( short )0xFFE8, + ( short )0xFFB0, ( short )0xFF90, ( short )0xFF88, ( short )0xFF70, + ( short )0xFF60, ( short )0xFF60, ( short )0xFF90, ( short )0xFFC0, + ( short )0xFFD0, ( short )0xFFD8, ( short )0xFFE0, ( short )0xFFE8, + ( short )0x0018, ( short )0x0050, ( short )0x0058, ( short )0x0030, + ( short )0x0008, ( short )0x0000, ( short )0x0018, ( short )0x0038, + ( short )0x0038, ( short )0x0048, ( short )0x0050, ( short )0x0050, + ( short )0x0020, ( short )0x0000, ( short )0xFFF8, ( short )0xFFB0, + ( short )0xFF70, ( short )0xFF68, ( short )0xFFB0, ( short )0xFFE8, + ( short )0xFFF8, ( short )0xFFF8, ( short )0xFFF8, ( short )0xFFF0, + ( short )0x0030, ( short )0x0070, ( short )0x0090, ( short )0x0098, + ( short )0x0098, ( short )0x0090, ( short )0x00A0, ( short )0x00B0, + ( short )0x00B8, ( short )0x00C0, ( short )0x00C0, ( short )0x00A8, + ( short )0x0098, ( short )0x0088, ( short )0x0078, ( short )0x0050, + ( short )0x0030, ( short )0x0020, ( short )0xFFD8, ( short )0xFF98, + ( short )0xFF88, ( short )0xFF50, ( short )0xFF20, ( short )0xFF18, + ( short )0xFEF8, ( short )0xFEE0, ( short )0xFEE8, ( short )0xFE70, + ( short )0xFE08, ( short )0xFE00, ( short )0xFE48, ( short )0xFE98, + ( short )0xFEB8, ( short )0xFEE8, ( short )0xFF10, ( short )0xFF28, + ( short )0xFF18, ( short )0xFF10, ( short )0xFF18, ( short )0xFF48, + ( short )0xFF70, ( short )0xFF88, ( short )0xFFE0, ( short )0x0028, + ( short )0x0040, ( short )0x0058, ( short )0x0068, ( short )0x0070, + ( short )0x0078, ( short )0x0070, ( short )0x0068, ( short )0x0068, + ( short )0x0078, ( short )0x0080, ( short )0x0080, ( short )0x0088, + ( short )0x0088, ( short )0x0080, ( short )0x0058, ( short )0x0030, + ( short )0x0020, ( short )0x0018, ( short )0x0018, ( short )0x0018, + ( short )0x0050, ( short )0x0090, ( short )0x00A0, ( short )0x0080, + ( short )0x0060, ( short )0x0050, ( short )0x0030, ( short )0x0018, + ( short )0x0010, ( short )0x0028, ( short )0x0038, ( short )0x0038, + ( short )0x0018, ( short )0xFFF8, ( short )0xFFF0, ( short )0x0000, + ( short )0x0020, ( short )0x0020, ( short )0x0030, ( short )0x0030, + ( short )0x0030, ( short )0x0040, ( short )0x0050, ( short )0x0050, + ( short )0x0050, ( short )0x0048, ( short )0x0048, ( short )0x0048, + ( short )0x0048, ( short )0x0048, ( short )0x0078, ( short )0x00A0, + ( short )0x00A8, ( short )0x00C0, ( short )0x00C8, ( short )0x00C0, + ( short )0x00D0, ( short )0x00E0, ( short )0x00D8, ( short )0x00E8, + ( short )0x00F0, ( short )0x00E0, ( short )0x0100, ( short )0x0118, + ( short )0x0110, ( short )0x0100, ( short )0x00F0, ( short )0x00D8, + ( short )0x0090, ( short )0x0048, ( short )0x0028, ( short )0x0020, + ( short )0x0020, ( short )0x0020, ( short )0x0038, ( short )0x0050, + ( short )0x0050, ( short )0x0050, ( short )0x0048, ( short )0x0040, + ( short )0x0050, ( short )0x0060, ( short )0x0060, ( short )0x0040, + ( short )0xFFC0, ( short )0xFF58, ( short )0xFF40, ( short )0xFF90, + ( short )0xFFE8, ( short )0x0000, ( short )0x0020, ( short )0x0030, + ( short )0x0030, ( short )0x0068, ( short )0x0098, ( short )0x00A8, + ( short )0x0110, ( short )0x0168, ( short )0x0170, ( short )0x0148, + ( short )0x0118, ( short )0x00F0, ( short )0x00E8, ( short )0x00E0, + ( short )0x00D0, ( short )0x0098, ( short )0x0060, ( short )0x0040, + ( short )0x0000, ( short )0xFFD8, ( short )0xFFD8, ( short )0xFFC0, + ( short )0xFFB0, ( short )0xFFB0, ( short )0xFF78, ( short )0xFF30, + ( short )0xFF10, ( short )0xFEF0, ( short )0xFEE8, ( short )0xFEF0, + ( short )0xFEC8, ( short )0xFED0, ( short )0xFEF8, ( short )0xFF00, + ( short )0xFF10, ( short )0xFF20, ( short )0xFF50, ( short )0xFF78, + ( short )0xFF90, ( short )0xFF80, ( short )0xFF70, ( short )0xFF70, + ( short )0xFF80, ( short )0xFF98, ( short )0xFFA0, ( short )0xFFB8, + ( short )0xFFD0, ( short )0xFFD8, ( short )0xFFF0, ( short )0x0000, + ( short )0x0008, ( short )0x0028, ( short )0x0048, ( short )0x0058, + ( short )0x0078, ( short )0x0070, ( short )0x0058, ( short )0x0068, + ( short )0x0098, ( short )0x00B8, ( short )0x00D8, ( short )0x00F0, + ( short )0x00F0, ( short )0x00E8, ( short )0x00F8, ( short )0x0100, + ( short )0x00D8, ( short )0x00D0, ( short )0x00C8, ( short )0x00E8, + ( short )0x0100, ( short )0x00F0, ( short )0x00E0, ( short )0x00C8, + ( short )0x00B8, ( short )0x00A0, ( short )0x0078, ( short )0x0058, + ( short )0x0038, ( short )0x0020, ( short )0x0010, ( short )0x0010, + ( short )0x0018, ( short )0x0010, ( short )0x0010, ( short )0x0010, + ( short )0x0018, ( short )0x0028, ( short )0x0008, ( short )0xFFE0, + ( short )0xFFC8, ( short )0xFF80, ( short )0xFF48, ( short )0xFF38, + ( short )0xFF40, ( short )0xFF48, ( short )0xFF48, ( short )0xFF70, + ( short )0xFF90, ( short )0xFFA8, ( short )0xFFB8, ( short )0xFFC0, + ( short )0xFFC8, ( short )0xFFC0, ( short )0xFFC0, ( short )0xFFC0, + ( short )0xFFB0, ( short )0xFFA0, ( short )0xFFA0, ( short )0xFFA0, + ( short )0xFFA8, ( short )0xFFB0, ( short )0xFF68, ( short )0xFF28, + ( short )0xFF08, ( short )0xFEF8, ( short )0xFEF8, ( short )0xFEE8, + ( short )0xFEE0, ( short )0xFED8, ( short )0xFEA8, ( short )0xFE98, + ( short )0xFEA8, ( short )0xFEA8, ( short )0xFEA0, ( short )0xFEA0, + ( short )0xFED0, ( short )0xFF00, ( short )0xFF30, ( short )0xFF28, + ( short )0xFF38, ( short )0xFF58, ( short )0xFF48, ( short )0xFF40, + ( short )0xFF48, ( short )0xFFB0, ( short )0x0010, ( short )0x0038, + ( short )0x0028, ( short )0x0010, ( short )0x0008, ( short )0x0050, + ( short )0x00A0, ( short )0x00B8, ( short )0x00A0, ( short )0x0080, + ( short )0x0070, ( short )0x0090, ( short )0x00B0, ( short )0x00B0, + ( short )0x00B8, ( short )0x00B8, ( short )0x00B0, ( short )0x00C0, + ( short )0x00D0, ( short )0x00C8, ( short )0x00A0, ( short )0x0068, + ( short )0x0038, ( short )0xFFF0, ( short )0xFFB0, ( short )0xFF88, + ( short )0xFF78, ( short )0xFF68, ( short )0xFF60, ( short )0xFF90, + ( short )0xFFC0, ( short )0xFFE0, ( short )0x0000, ( short )0x0020, + ( short )0x0030, ( short )0x00A0, ( short )0x0110, ( short )0x0138, + ( short )0x0140, ( short )0x0148, ( short )0x0148, ( short )0x0110, + ( short )0x00E8, ( short )0x00C0, ( short )0x00A0, ( short )0x0088, + ( short )0x0068, ( short )0x0008, ( short )0xFFB0, ( short )0xFF88, + ( short )0xFF58, ( short )0xFF30, ( short )0xFF20, ( short )0xFEF8, + ( short )0xFED8, ( short )0xFED8, ( short )0xFF00, ( short )0xFF20, + ( short )0xFF38, ( short )0xFF50, ( short )0xFF68, ( short )0xFF88, + ( short )0xFFA0, ( short )0xFFB8, ( short )0x0020, ( short )0x0080, + ( short )0x00A0, ( short )0x00D8, ( short )0x0100, ( short )0x0100, + ( short )0x0138, ( short )0x0168, ( short )0x0148, ( short )0x0128, + ( short )0x0120, ( short )0x00F8, ( short )0x00E8, ( short )0x00E0, + ( short )0x00C0, ( short )0x00A8, ( short )0x00B0, ( short )0x0098, + ( short )0x0070, ( short )0x0048, ( short )0x0030, ( short )0xFFD0, + ( short )0xFF60, ( short )0xFF48, ( short )0xFF10, ( short )0xFEA8, + ( short )0xFEA8, ( short )0xFEC0, ( short )0xFEC0, ( short )0xFEE8, + ( short )0xFEB0, ( short )0xFE58, ( short )0xFE88, ( short )0xFED0, + ( short )0xFEB8, ( short )0xFE48, ( short )0xFE58, ( short )0xFEE8, + ( short )0xFF28, ( short )0xFF18, ( short )0xFF60, ( short )0x00A0, + ( short )0x01A0, ( short )0x0188, ( short )0x0178, ( short )0x0208, + ( short )0x0208, ( short )0x0100, ( short )0x0018, ( short )0xFFE0, + ( short )0xFEE0, ( short )0xFD68, ( short )0xFD00, ( short )0xFD60, + ( short )0xFD70, ( short )0xFDA8, ( short )0xFF00, ( short )0x00A0, + ( short )0x0170, ( short )0x0210, ( short )0x02D8, ( short )0x0310, + ( short )0x0218, ( short )0x00A0, ( short )0xFFA0, ( short )0xFDF0, + ( short )0xFBD8, ( short )0xFB08, ( short )0xF9C0, ( short )0xF830, + ( short )0xF8D8, ( short )0xFCC0, ( short )0x0038, ( short )0x01A0, + ( short )0x0380, ( short )0x0A18, ( short )0x0F50, ( short )0x0DB0, + ( short )0x0C30, ( short )0x0E18, ( short )0x0CA8, ( short )0x0570, + ( short )0xFF98, ( short )0xFE38, ( short )0xFBA0, ( short )0xF700, + ( short )0xF5D0, ( short )0xF7C8, ( short )0xF9A8, ( short )0xFB48, + ( short )0xFBB0, ( short )0xFC78, ( short )0xFF00, ( short )0xFE98, + ( short )0xFB20, ( short )0xFA48, ( short )0xFAC0, ( short )0xF8C8, + ( short )0xF6E0, ( short )0xF9C0, ( short )0xFE08, ( short )0xFF80, + ( short )0x0428, ( short )0x0B70, ( short )0x0E18, ( short )0x0D38, + ( short )0x0D38, ( short )0x0C28, ( short )0x01D0, ( short )0xF578, + ( short )0xF108, ( short )0xFB50, ( short )0x0498, ( short )0x0428, + ( short )0x0CE8, ( short )0x2190, ( short )0x29F0, ( short )0x22E0, + ( short )0x1F68, ( short )0x2050, ( short )0x1810, ( short )0x0710, + ( short )0xFA98, ( short )0xF438, ( short )0xEE68, ( short )0xE950, + ( short )0xEBC8, ( short )0xF538, ( short )0xFEB8, ( short )0x0240, + ( short )0x0460, ( short )0x09D0, ( short )0x0978, ( short )0xFFF8, + ( short )0xF810, ( short )0xF190, ( short )0xE8D0, ( short )0xE290, + ( short )0xDF60, ( short )0xDFF0, ( short )0xE668, ( short )0xEC20, + ( short )0xF138, ( short )0xFAC0, ( short )0x04F0, ( short )0x08D0, + ( short )0x08C8, ( short )0x0B18, ( short )0x09F8, ( short )0x0230, + ( short )0xFA38, ( short )0xFA68, ( short )0xFC78, ( short )0xF9B8, + ( short )0xF850, ( short )0xFEA8, ( short )0x05B8, ( short )0x0690, + ( short )0x02E8, ( short )0x0268, ( short )0x0498, ( short )0xFCB0, + ( short )0xF018, ( short )0xEDF8, ( short )0x0090, ( short )0x0F48, + ( short )0x0C70, ( short )0x1278, ( short )0x27B8, ( short )0x2EA0, + ( short )0x21F8, ( short )0x1920, ( short )0x1918, ( short )0x1530, + ( short )0x0638, ( short )0xF858, ( short )0xF720, ( short )0xF9F8, + ( short )0xF600, ( short )0xF850, ( short )0x0590, ( short )0x0EE0, + ( short )0x1000, ( short )0x10D8, ( short )0x1460, ( short )0x10F8, + ( short )0x0500, ( short )0xFBC0, ( short )0xF7A8, ( short )0xF250, + ( short )0xEC00, ( short )0xEB30, ( short )0xF1C8, ( short )0xF920, + ( short )0xFC90, ( short )0x0190, ( short )0x0A60, ( short )0x0E80, + ( short )0x0DB0, ( short )0x0AD8, ( short )0x0690, ( short )0x0168, + ( short )0xFF20, ( short )0xFBD0, ( short )0xF6F8, ( short )0xF660, + ( short )0xF680, ( short )0xF5B0, ( short )0xF7C0, ( short )0xF120, + ( short )0xEA90, ( short )0xF030, ( short )0xEC18, ( short )0xE190, + ( short )0xE558, ( short )0xFF20, ( short )0x1090, ( short )0x0C50, + ( short )0x1248, ( short )0x2788, ( short )0x2AD0, ( short )0x1628, + ( short )0x08F0, ( short )0x0BA8, ( short )0x0538, ( short )0xEF48, + ( short )0xE410, ( short )0xEB10, ( short )0xEF68, ( short )0xEA28, + ( short )0xEC40, ( short )0xFC18, ( short )0x08A8, ( short )0x0818, + ( short )0x0778, ( short )0x0858, ( short )0x02F8, ( short )0xF8E8, + ( short )0xF1F0, ( short )0xEF40, ( short )0xECD0, ( short )0xE958, + ( short )0xEA70, ( short )0xF260, ( short )0xFAF0, ( short )0xFFA0, + ( short )0x04A0, ( short )0x0CF8, ( short )0x10F8, ( short )0x0EA0, + ( short )0x0D48, ( short )0x0BE8, ( short )0x05E0, ( short )0x03B0, + ( short )0x0358, ( short )0xFF18, ( short )0xFB40, ( short )0xF9B0, + ( short )0xF9C0, ( short )0xF7C0, ( short )0xEE90, ( short )0xEAA0, + ( short )0xEE00, ( short )0xE888, ( short )0xE200, ( short )0xEF00, + ( short )0x0948, ( short )0x1400, ( short )0x1270, ( short )0x1D88, + ( short )0x2CD8, ( short )0x2488, ( short )0x0DA8, ( short )0x04B8, + ( short )0x0548, ( short )0xF7B0, ( short )0xE3F0, ( short )0xE268, + ( short )0xEFF8, ( short )0xF5A0, ( short )0xF320, ( short )0xFC68, + ( short )0x0BF0, ( short )0x0FA0, ( short )0x0A50, ( short )0x01F8, + ( short )0xFE60, ( short )0xFC48, ( short )0xF340, ( short )0xEB28, + ( short )0xED58, ( short )0xF3C0, ( short )0xF5B8, ( short )0xF738, + ( short )0x00F8, ( short )0x0C70, ( short )0x0E90, ( short )0x0DE8, + ( short )0x1190, ( short )0x12B0, ( short )0x1058, ( short )0x0B98, + ( short )0x0638, ( short )0x0868, ( short )0x0998, ( short )0x02B0, + ( short )0xFE50, ( short )0x0120, ( short )0x02A0, ( short )0xFC90, + ( short )0xF810, ( short )0xF9D0, ( short )0xF818, ( short )0xF290, + ( short )0xF240, ( short )0xF6D0, ( short )0x0A48, ( short )0x1AD8, + ( short )0x1840, ( short )0x1C18, ( short )0x2B18, ( short )0x29F0, + ( short )0x1608, ( short )0x08B8, ( short )0x0778, ( short )0x0128, + ( short )0xF118, ( short )0xE868, ( short )0xEDA0, ( short )0xF310, + ( short )0xF248, ( short )0xF558, ( short )0x0058, ( short )0x0970, + ( short )0x0688, ( short )0x0108, ( short )0xFD08, ( short )0xF988, + ( short )0xF558, ( short )0xF0A0, ( short )0xF0B0, ( short )0xF540, + ( short )0xF6E8, ( short )0xFCA0, ( short )0x0758, ( short )0x0CD0, + ( short )0x0F60, ( short )0x1338, ( short )0x1458, ( short )0x1278, + ( short )0x0FD0, ( short )0x0CA8, ( short )0x0D50, ( short )0x0D10, + ( short )0x0798, ( short )0x0398, ( short )0x0428, ( short )0x04F0, + ( short )0x0278, ( short )0xFF98, ( short )0x0178, ( short )0x0088, + ( short )0xFB08, ( short )0xF660, ( short )0xF1A8, ( short )0xEF18, + ( short )0xF9E8, ( short )0x0C00, ( short )0x11C8, ( short )0x1260, + ( short )0x1B60, ( short )0x21B0, ( short )0x18E0, ( short )0x0B08, + ( short )0x04C8, ( short )0x0078, ( short )0xF730, ( short )0xEF60, + ( short )0xEB18, ( short )0xEC10, ( short )0xF290, ( short )0xF800, + ( short )0xFB60, ( short )0xFF60, ( short )0x0080, ( short )0xFFA8, + ( short )0xFB08, ( short )0xF1A8, ( short )0xED10, ( short )0xEFF0, + ( short )0xEED0, ( short )0xEB10, ( short )0xEFE8, ( short )0xF8F0, + ( short )0xFDE0, ( short )0x0298, ( short )0x0528, ( short )0x0598, + ( short )0x0928, ( short )0x0A30, ( short )0x0670, ( short )0x08E8, + ( short )0x0BC0, ( short )0x0698, ( short )0x0210, ( short )0x0390, + ( short )0x0560, ( short )0x0288, ( short )0xF910, ( short )0xF468, + ( short )0xF560, ( short )0xF3E0, ( short )0xEE10, ( short )0xE8B0, + ( short )0xE508, ( short )0xEED0, ( short )0x03E0, ( short )0x0638, + ( short )0xFFA8, ( short )0x0BB8, ( short )0x2078, ( short )0x1FA8, + ( short )0x0EF0, ( short )0x0648, ( short )0x05C8, ( short )0xFF18, + ( short )0xF588, ( short )0xEE20, ( short )0xED88, ( short )0xF5A0, + ( short )0xFBA8, ( short )0xFBC0, ( short )0xFA98, ( short )0xFA20, + ( short )0xF7D8, ( short )0xF2D0, ( short )0xEF48, ( short )0xE998, + ( short )0xE378, ( short )0xE530, ( short )0xE868, ( short )0xE890, + ( short )0xEDD0, ( short )0xF798, ( short )0xFBC0, ( short )0xFD20, + ( short )0x0178, ( short )0x0490, ( short )0x04A0, ( short )0x0758, + ( short )0x0858, ( short )0x0490, ( short )0x04F8, ( short )0x0858, + ( short )0x06F0, ( short )0x05F8, ( short )0x0450, ( short )0x0098, + ( short )0xFE60, ( short )0xFDA0, ( short )0xF9E0, ( short )0xF358, + ( short )0xEDC0, ( short )0xF308, ( short )0xFFE0, ( short )0x0018, + ( short )0xFB80, ( short )0x0948, ( short )0x1DB8, ( short )0x1D08, + ( short )0x0F88, ( short )0x0B48, ( short )0x0C50, ( short )0x09C0, + ( short )0xFF78, ( short )0xF1A0, ( short )0xEF28, ( short )0xF6B8, + ( short )0xF9F0, ( short )0xF6F0, ( short )0xF688, ( short )0xF9E0, + ( short )0xF9C0, ( short )0xF4C8, ( short )0xEBD8, ( short )0xE7E8, + ( short )0xEBE0, ( short )0xE8C8, ( short )0xE100, ( short )0xE518, + ( short )0xF0B8, ( short )0xF728, ( short )0xF770, ( short )0xF878, + ( short )0xFF58, ( short )0x06B0, ( short )0x0430, ( short )0x0060, + ( short )0x0390, ( short )0x0A18, ( short )0x0B98, ( short )0x06C8, + ( short )0x0710, ( short )0x0CF0, ( short )0x08D0, ( short )0x01F8, + ( short )0x0280, ( short )0x0238, ( short )0xFD78, ( short )0xF868, + ( short )0xF198, ( short )0xF670, ( short )0x0930, ( short )0x0A78, + ( short )0xFB38, ( short )0x04F0, ( short )0x1EB8, ( short )0x1E98, + ( short )0x0F68, ( short )0x0EC8, ( short )0x1548, ( short )0x1480, + ( short )0x0C60, ( short )0x00B0, ( short )0xFEF8, ( short )0x0830, + ( short )0x0838, ( short )0x0160, ( short )0x0380, ( short )0x07E8, + ( short )0x0270, ( short )0xFBA0, ( short )0xF9C0, ( short )0xF450, + ( short )0xEE08, ( short )0xED08, ( short )0xEE10, ( short )0xEF20, + ( short )0xF1C0, ( short )0xF800, ( short )0xFE70, ( short )0x00B0, + ( short )0x02D8, ( short )0x07C8, ( short )0x09F0, ( short )0x09A8, + ( short )0x0A60, ( short )0x0B28, ( short )0x0C80, ( short )0x0D58, + ( short )0x0BD0, ( short )0x0A48, ( short )0x0900, ( short )0x0768, + ( short )0x03D0, ( short )0x00E0, ( short )0xFFF8, ( short )0xFBD8, + ( short )0xF5E8, ( short )0xFE18, ( short )0x0FE8, ( short )0x1060, + ( short )0x05C8, ( short )0x1078, ( short )0x2638, ( short )0x2580, + ( short )0x1740, ( short )0x14E8, ( short )0x19D0, ( short )0x17D8, + ( short )0x0E10, ( short )0x0270, ( short )0x0120, ( short )0x0900, + ( short )0x0870, ( short )0x0290, ( short )0x03A0, ( short )0x0600, + ( short )0x0100, ( short )0xFE28, ( short )0xFF28, ( short )0xF838, + ( short )0xF0B8, ( short )0xF238, ( short )0xF530, ( short )0xF440, + ( short )0xF440, ( short )0xFA38, ( short )0x0198, ( short )0x03A8, + ( short )0x03D0, ( short )0x0780, ( short )0x0AB8, ( short )0x0B58, + ( short )0x0B10, ( short )0x0AD8, ( short )0x0A08, ( short )0x0878, + ( short )0x07C8, ( short )0x0648, ( short )0x01A0, ( short )0xFF48, + ( short )0xFE58, ( short )0xFA68, ( short )0xF7D0, ( short )0xF758, + ( short )0xF470, ( short )0xF5B0, ( short )0x02A8, ( short )0x0A58, + ( short )0x0448, ( short )0x07C8, ( short )0x1708, ( short )0x1970, + ( short )0x0EC8, ( short )0x0A40, ( short )0x0CD0, ( short )0x0D28, + ( short )0x0838, ( short )0x0010, ( short )0xFAE0, ( short )0xFCB0, + ( short )0xFEB8, ( short )0xFCE8, ( short )0xFBA8, ( short )0xFD10, + ( short )0xFBC8, ( short )0xF910, ( short )0xF960, ( short )0xF830, + ( short )0xF4D8, ( short )0xF500, ( short )0xF860, ( short )0xF9F0, + ( short )0xFB58, ( short )0xFE48, ( short )0x0050, ( short )0x0418, + ( short )0x0910, ( short )0x0940, ( short )0x0830, ( short )0x0AC8, + ( short )0x0C88, ( short )0x0A50, ( short )0x07C0, ( short )0x0700, + ( short )0x0590, ( short )0x0268, ( short )0xFFF0, ( short )0xFBA8, + ( short )0xF720, ( short )0xF698, ( short )0xF2E0, ( short )0xEB68, + ( short )0xEDA0, ( short )0xFC00, ( short )0x0358, ( short )0xFF30, + ( short )0x0398, ( short )0x1220, ( short )0x1860, ( short )0x1368, + ( short )0x10C0, ( short )0x12F0, ( short )0x12A0, ( short )0x0E08, + ( short )0x0780, ( short )0x0010, ( short )0xFAD8, ( short )0xF990, + ( short )0xF7E0, ( short )0xF278, ( short )0xEE10, ( short )0xEB98, + ( short )0xE7A0, ( short )0xE6F8, ( short )0xEA30, ( short )0xE980, + ( short )0xE420, ( short )0xE440, ( short )0xEBA8, ( short )0xEF98, + ( short )0xEF68, ( short )0xF288, ( short )0xF7A8, ( short )0xFC90, + ( short )0x01F8, ( short )0x0528, ( short )0x0630, ( short )0x08E8, + ( short )0x0C98, ( short )0x0D50, ( short )0x0B98, ( short )0x0920, + ( short )0x0678, ( short )0x03F0, ( short )0x0260, ( short )0xFE00, + ( short )0xF810, ( short )0xF4B8, ( short )0xF0C0, ( short )0xEB68, + ( short )0xEF58, ( short )0xFAE8, ( short )0xFDE0, ( short )0xF680, + ( short )0xF910, ( short )0x06E0, ( short )0x0C20, ( short )0x05D8, + ( short )0x0408, ( short )0x05C8, ( short )0x0450, ( short )0x02D0, + ( short )0x0128, ( short )0xFB78, ( short )0xF668, ( short )0xF430, + ( short )0xF150, ( short )0xED90, ( short )0xE870, ( short )0xE448, + ( short )0xE2E0, ( short )0xE048, ( short )0xDDD0, ( short )0xDF08, + ( short )0xE0E0, ( short )0xE098, ( short )0xE258, ( short )0xE520, + ( short )0xE6A8, ( short )0xEA28, ( short )0xEF88, ( short )0xF2A8, + ( short )0xF548, ( short )0xFBA8, ( short )0x01C8, ( short )0x03F8, + ( short )0x0748, ( short )0x0C88, ( short )0x0E98, ( short )0x0DB8, + ( short )0x0D98, ( short )0x0D50, ( short )0x0B68, ( short )0x0970, + ( short )0x06C0, ( short )0x0238, ( short )0xFE18, ( short )0xFB08, + ( short )0xF820, ( short )0xF780, ( short )0xF970, ( short )0xF9B0, + ( short )0xF880, ( short )0xFA28, ( short )0x0028, ( short )0x0698, + ( short )0x0948, ( short )0x08D0, ( short )0x09E0, ( short )0x0DD0, + ( short )0x1010, ( short )0x0D40, ( short )0x0958, ( short )0x0728, + ( short )0x0308, ( short )0xFDA0, ( short )0xF9F8, ( short )0xF418, + ( short )0xEC98, ( short )0xE8B8, ( short )0xE618, ( short )0xE200, + ( short )0xDED0, ( short )0xDF48, ( short )0xE100, ( short )0xE180, + ( short )0xE160, ( short )0xE3C8, ( short )0xE898, ( short )0xEDD8, + ( short )0xF250, ( short )0xF558, ( short )0xFB00, ( short )0x02F8, + ( short )0x07B0, ( short )0x0B80, ( short )0x1108, ( short )0x1518, + ( short )0x1660, ( short )0x1770, ( short )0x1870, ( short )0x16F8, + ( short )0x1300, ( short )0x0F78, ( short )0x0FC0, ( short )0x1070, + ( short )0x0CE8, ( short )0x0AF8, ( short )0x0BD8, ( short )0x0D28, + ( short )0x10A8, ( short )0x1370, ( short )0x10A0, ( short )0x1040, + ( short )0x1518, ( short )0x1740, ( short )0x1550, ( short )0x1398, + ( short )0x10E0, ( short )0x0AC8, ( short )0x0640, ( short )0x0348, + ( short )0xFD18, ( short )0xF658, ( short )0xF1D8, ( short )0xEC20, + ( short )0xE760, ( short )0xE550, ( short )0xE4B8, ( short )0xE418, + ( short )0xE438, ( short )0xE508, ( short )0xE738, ( short )0xEB18, + ( short )0xF0C8, ( short )0xF618, ( short )0xF988, ( short )0xFEC8, + ( short )0x0518, ( short )0x09D8, ( short )0x1118, ( short )0x17F0, + ( short )0x1BB0, ( short )0x1E28, ( short )0x2120, ( short )0x23D8, + ( short )0x2638, ( short )0x2418, ( short )0x2080, ( short )0x1D30, + ( short )0x1CE8, ( short )0x1D98, ( short )0x1CA8, ( short )0x1AD8, + ( short )0x1960, ( short )0x17F8, ( short )0x1A40, ( short )0x1CF8, + ( short )0x1D38, ( short )0x1C30, ( short )0x1A68, ( short )0x1860, + ( short )0x1480, ( short )0x1020, ( short )0x0B68, ( short )0x03E8, + ( short )0xFBA8, ( short )0xF508, ( short )0xEE40, ( short )0xE820, + ( short )0xE338, ( short )0xDE88, ( short )0xDA30, ( short )0xD7D0, + ( short )0xD728, ( short )0xD7D8, ( short )0xD998, ( short )0xDC10, + ( short )0xDFB0, ( short )0xE470, ( short )0xE948, ( short )0xEF98, + ( short )0xF5F0, ( short )0xFC38, ( short )0x0228, ( short )0x0798, + ( short )0x0D98, ( short )0x1320, ( short )0x1760, ( short )0x1A70, + ( short )0x1BE0, ( short )0x1CC0, ( short )0x1D98, ( short )0x1A88, + ( short )0x1658, ( short )0x12A0, ( short )0x1180, ( short )0x10A8, + ( short )0x0ED0, ( short )0x0CC8, ( short )0x0AD8, ( short )0x0920, + ( short )0x0B70, ( short )0x0E30, ( short )0x0EE8, ( short )0x0D80, + ( short )0x0BE0, ( short )0x0AC0, ( short )0x09B8, ( short )0x0890, + ( short )0x0690, ( short )0x01F8, ( short )0xFD30, ( short )0xF9F0, + ( short )0xF5B0, ( short )0xF188, ( short )0xEE38, ( short )0xE9E8, + ( short )0xE5E8, ( short )0xE3E0, ( short )0xE4A0, ( short )0xE608, + ( short )0xE738, ( short )0xE858, ( short )0xE980, ( short )0xEC20, + ( short )0xF030, ( short )0xF450, ( short )0xF878, ( short )0xFC68, + ( short )0xFF68, ( short )0x03C8, ( short )0x08B8, ( short )0x0D00, + ( short )0x1038, ( short )0x12D8, ( short )0x1490, ( short )0x1648, + ( short )0x16B8, ( short )0x1468, ( short )0x1160, ( short )0x0FA8, + ( short )0x1038, ( short )0x1058, ( short )0x0F88, ( short )0x0E50, + ( short )0x0CC8, ( short )0x0CC0, ( short )0x0FC0, ( short )0x1220, + ( short )0x12A0, ( short )0x10F8, ( short )0x0F20, ( short )0x0D28, + ( short )0x0C78, ( short )0x0BB8, ( short )0x08D0, ( short )0x01C8, + ( short )0xFB38, ( short )0xF660, ( short )0xF330, ( short )0xF078, + ( short )0xEC28, ( short )0xE6C8, ( short )0xE2C0, ( short )0xE050, + ( short )0xDFC8, ( short )0xE038, ( short )0xE160, ( short )0xE300, + ( short )0xE568, ( short )0xE6B8, ( short )0xE9A0, ( short )0xED50, + ( short )0xF238, ( short )0xF6D8, ( short )0xFB08, ( short )0xFF10, + ( short )0x02E8, ( short )0x06A0, ( short )0x0AC0, ( short )0x0DC8, + ( short )0x1010, ( short )0x1168, ( short )0x1018, ( short )0x0E90, + ( short )0x0BF8, ( short )0x0B08, ( short )0x0A50, ( short )0x09F0, + ( short )0x0960, ( short )0x0888, ( short )0x0808, ( short )0x09C8, + ( short )0x0BA8, ( short )0x0EE8, ( short )0x1070, ( short )0x10D0, + ( short )0x0F58, ( short )0x0D60, ( short )0x0BA0, ( short )0x0A60, + ( short )0x08F0, ( short )0x0608, ( short )0xFFB0, ( short )0xF938, + ( short )0xF360, ( short )0xF030, ( short )0xEE20, ( short )0xEB70, + ( short )0xE7A8, ( short )0xE410, ( short )0xE140, ( short )0xDFC8, + ( short )0xDFF8, ( short )0xE1F0, ( short )0xE448, ( short )0xE6D0, + ( short )0xE780, ( short )0xE9E8, ( short )0xECF0, ( short )0xF248, + ( short )0xF730, ( short )0xFBC0, ( short )0xFF80, ( short )0x0310, + ( short )0x0670, ( short )0x0A98, ( short )0x0D88, ( short )0x0FD8, + ( short )0x10C0, ( short )0x0EB0, ( short )0x0C48, ( short )0x08B8, + ( short )0x0998, ( short )0x0AC0, ( short )0x0C68, ( short )0x0B78, + ( short )0x09C8, ( short )0x0838, ( short )0x08F8, ( short )0x0A80, + ( short )0x0CA0, ( short )0x0E10, ( short )0x0E48, ( short )0x0D58, + ( short )0x0A28, ( short )0x0750, ( short )0x04F0, ( short )0x0228, + ( short )0xFEE8, ( short )0xFA80, ( short )0xF468, ( short )0xEED0, + ( short )0xEAE0, ( short )0xE8B8, ( short )0xE718, ( short )0xE5B0, + ( short )0xE4A8, ( short )0xE410, ( short )0xE480, ( short )0xE548, + ( short )0xE738, ( short )0xE9B0, ( short )0xED80, ( short )0xF0B8, + ( short )0xF480, ( short )0xF7B0, ( short )0xFB70, ( short )0xFED0, + ( short )0x0328, ( short )0x0720, ( short )0x0A98, ( short )0x0E00, + ( short )0x10F8, ( short )0x12E0, ( short )0x12A8, ( short )0x11B0, + ( short )0x0F58, ( short )0x0F38, ( short )0x0E88, ( short )0x0F08, + ( short )0x0FC0, ( short )0x0FF0, ( short )0x10B8, ( short )0x1138, + ( short )0x1198, ( short )0x13D0, ( short )0x1638, ( short )0x17E8, + ( short )0x1758, ( short )0x1628, ( short )0x1460, ( short )0x10E8, + ( short )0x0CA0, ( short )0x0848, ( short )0x0280, ( short )0xFC90, + ( short )0xF700, ( short )0xF0F8, ( short )0xEB18, ( short )0xE638, + ( short )0xE1B8, ( short )0xDE78, ( short )0xDC58, ( short )0xDBB8, + ( short )0xDC28, ( short )0xDDB0, ( short )0xE030, ( short )0xE330, + ( short )0xE6F0, ( short )0xEC20, ( short )0xF210, ( short )0xF7C0, + ( short )0xFCE0, ( short )0x0150, ( short )0x0570, ( short )0x08F0, + ( short )0x0C70, ( short )0x0F50, ( short )0x12B8, ( short )0x1560, + ( short )0x16E0, ( short )0x1630, ( short )0x14E8, ( short )0x1298, + ( short )0x11B8, ( short )0x1170, ( short )0x11B8, ( short )0x11C0, + ( short )0x0FE8, ( short )0x0E58, ( short )0x0CB8, ( short )0x0C50, + ( short )0x0D68, ( short )0x0E98, ( short )0x0E30, ( short )0x0C28, + ( short )0x0A10, ( short )0x06D8, ( short )0x02E0, ( short )0xFEA0, + ( short )0xFA18, ( short )0xF4E8, ( short )0xF018, ( short )0xEB68, + ( short )0xE6E8, ( short )0xE310, ( short )0xDFC8, ( short )0xDD38, + ( short )0xDBF8, ( short )0xDC38, ( short )0xDDD0, ( short )0xE070, + ( short )0xE390, ( short )0xE760, ( short )0xEB88, ( short )0xEF20, + ( short )0xF378, ( short )0xF830, ( short )0xFCE0, ( short )0x00F8, + ( short )0x0480, ( short )0x0768, ( short )0x0968, ( short )0x0AE0, + ( short )0x0BB8, ( short )0x0C10, ( short )0x0BB0, ( short )0x0A78, + ( short )0x08E0, ( short )0x06E8, ( short )0x0540, ( short )0x0870, + ( short )0x0BE0, ( short )0x0ED0, ( short )0x0E40, ( short )0x0D10, + ( short )0x0CC8, ( short )0x0E28, ( short )0x0FA0, ( short )0x0FB0, + ( short )0x0F18, ( short )0x0DD0, ( short )0x0BC8, ( short )0x08E8, + ( short )0x0628, ( short )0x0300, ( short )0xFF18, ( short )0xFB40, + ( short )0xF780, ( short )0xF388, ( short )0xF028, ( short )0xED80, + ( short )0xEB18, ( short )0xE968, ( short )0xE8C0, ( short )0xE738, + ( short )0xE658, ( short )0xE698, ( short )0xE888, ( short )0xEB38, + ( short )0xEDA0, ( short )0xF178, ( short )0xF5B8, ( short )0xFA28, + ( short )0xFEA8, ( short )0x0300, ( short )0x06C8, ( short )0x0960, + ( short )0x0B70, ( short )0x0CE0, ( short )0x0D70, ( short )0x0D50, + ( short )0x0C60, ( short )0x0890, ( short )0x0418, ( short )0x0028, + ( short )0x01D0, ( short )0x03F8, ( short )0x05A8, ( short )0x0700, + ( short )0x0808, ( short )0x09A0, ( short )0x0B18, ( short )0x0CC8, + ( short )0x0D90, ( short )0x0E68, ( short )0x0EC0, ( short )0x0E30, + ( short )0x0C28, ( short )0x09D8, ( short )0x0730, ( short )0x0308, + ( short )0xFED8, ( short )0xFAC0, ( short )0xF598, ( short )0xF0D8, + ( short )0xECE0, ( short )0xEAA8, ( short )0xE948, ( short )0xE8D0, + ( short )0xE850, ( short )0xE888, ( short )0xE910, ( short )0xEAD0, + ( short )0xED68, ( short )0xF018, ( short )0xF350, ( short )0xF6B8, + ( short )0xFAE0, ( short )0xFF00, ( short )0x02D8, ( short )0x05E8, + ( short )0x0830, ( short )0x09F8, ( short )0x0B08, ( short )0x0B80, + ( short )0x0B60, ( short )0x0988, ( short )0x0648, ( short )0x02D0, + ( short )0x0150, ( short )0x01E8, ( short )0x0270, ( short )0x03E0, + ( short )0x0538, ( short )0x0658, ( short )0x0918, ( short )0x0C00, + ( short )0x0E88, ( short )0x10B8, ( short )0x12A0, ( short )0x13E0, + ( short )0x1488, ( short )0x1448, ( short )0x1368, ( short )0x1120, + ( short )0x0DD0, ( short )0x0A40, ( short )0x0608, ( short )0x0148, + ( short )0xFC80, ( short )0xF860, ( short )0xF4D8, ( short )0xF1C0, + ( short )0xF008, ( short )0xEF38, ( short )0xEE78, ( short )0xEE98, + ( short )0xEF90, ( short )0xF170, ( short )0xF390, ( short )0xF5C0, + ( short )0xF888, ( short )0xFB48, ( short )0xFDF0, ( short )0x0078, + ( short )0x03D0, ( short )0x06C8, ( short )0x08F8, ( short )0x0AA0, + ( short )0x0BC8, ( short )0x0C48, ( short )0x0B30, ( short )0x0978, + ( short )0x06A8, ( short )0x0530, ( short )0x03F0, ( short )0x0438, + ( short )0x03C0, ( short )0x0350, ( short )0x0360, ( short )0x04E8, + ( short )0x0698, ( short )0x07D0, ( short )0x08D0, ( short )0x0998, + ( short )0x0A70, ( short )0x0B48, ( short )0x0B70, ( short )0x0AD0, + ( short )0x09C0, ( short )0x0890, ( short )0x0730, ( short )0x0588, + ( short )0x0358, ( short )0x0140, ( short )0xFF58, ( short )0xFD40, + ( short )0xFB68, ( short )0xF9E8, ( short )0xF828, ( short )0xF6D0, + ( short )0xF608, ( short )0xF5D8, ( short )0xF610, ( short )0xF668, + ( short )0xF778, ( short )0xF8E8, ( short )0xFA48, ( short )0xFCC8, + ( short )0xFF50, ( short )0x01C8, ( short )0x0428, ( short )0x0640, + ( short )0x07D0, ( short )0x09D0, ( short )0x0B40, ( short )0x0BF8, + ( short )0x0C30, ( short )0x0C08, ( short )0x0B08, ( short )0x0988, + ( short )0x07C0, ( short )0x0670, ( short )0x0608, ( short )0x0590, + ( short )0x0588, ( short )0x05B0, ( short )0x05E0, ( short )0x06B8, + ( short )0x0748, ( short )0x0758, ( short )0x0700, ( short )0x06A8, + ( short )0x0620, ( short )0x05D8, ( short )0x0590, ( short )0x0528, + ( short )0x03A8, ( short )0x0240, ( short )0x0108, ( short )0xFF38, + ( short )0xFD50, ( short )0xFBA0, ( short )0xFA38, ( short )0xF920, + ( short )0xF860, ( short )0xF6E8, ( short )0xF640, ( short )0xF628, + ( short )0xF680, ( short )0xF720, ( short )0xF800, ( short )0xF8E0, + ( short )0xF9A0, ( short )0xFA78, ( short )0xFB88, ( short )0xFD20, + ( short )0xFEA0, ( short )0x0008, ( short )0x0110, ( short )0x0200, + ( short )0x0360, ( short )0x04E0, ( short )0x0608, ( short )0x0738, + ( short )0x0838, ( short )0x08D8, ( short )0x0828, ( short )0x0738, + ( short )0x0600, ( short )0x04A8, ( short )0x02E0, ( short )0x0130, + ( short )0xFFA0, ( short )0xFF48, ( short )0xFF10, ( short )0xFEF0, + ( short )0xFF30, ( short )0xFFD0, ( short )0x0090, ( short )0x0090, + ( short )0x0070, ( short )0x0060, ( short )0xFFE8, ( short )0xFF50, + ( short )0xFEB8, ( short )0xFE98, ( short )0xFE88, ( short )0xFE80, + ( short )0xFE58, ( short )0xFE50, ( short )0xFE58, ( short )0xFDB0, + ( short )0xFD08, ( short )0xFC80, ( short )0xFAF8, ( short )0xF988, + ( short )0xF860, ( short )0xF798, ( short )0xF720, ( short )0xF6E8, + ( short )0xF728, ( short )0xF7C0, ( short )0xF8A8, ( short )0xF8F8, + ( short )0xF960, ( short )0xFA18, ( short )0xFAC0, ( short )0xFB58, + ( short )0xFC18, ( short )0xFCE0, ( short )0xFDA0, ( short )0xFE20, + ( short )0xFE88, ( short )0xFEF8, ( short )0xFEF0, ( short )0xFEC8, + ( short )0xFEA8, ( short )0xFDE0, ( short )0xFD10, ( short )0xFC70, + ( short )0xFBA8, ( short )0xFB10, ( short )0xFAB8, ( short )0xFAA0, + ( short )0xFAD0, ( short )0xFB18, ( short )0xFA90, ( short )0xFA18, + ( short )0xFA10, ( short )0xFA80, ( short )0xFB10, ( short )0xFB88, + ( short )0xFC90, ( short )0xFDB8, ( short )0xFEB8, ( short )0xFF80, + ( short )0x0058, ( short )0x0138, ( short )0x0118, ( short )0x00C8, + ( short )0x00C0, ( short )0xFF98, ( short )0xFE30, ( short )0xFD38, + ( short )0xFC68, ( short )0xFB78, ( short )0xFAB8, ( short )0xFAE8, + ( short )0xFB78, ( short )0xFBD0, ( short )0xFBE8, ( short )0xFC18, + ( short )0xFC98, ( short )0xFD28, ( short )0xFD48, ( short )0xFD68, + ( short )0xFD68, ( short )0xFD90, ( short )0xFDB8, ( short )0xFD90, + ( short )0xFD68, ( short )0xFD78, ( short )0xFCA0, ( short )0xFB70, + ( short )0xFAD0, ( short )0xF9F0, ( short )0xF870, ( short )0xF748, + ( short )0xF748, ( short )0xF770, ( short )0xF748, ( short )0xF720, + ( short )0xF7A8, ( short )0xF878, ( short )0xF930, ( short )0xF998, + ( short )0xFA38, ( short )0xFC10, ( short )0xFDA0, ( short )0xFE70, + ( short )0x0030, ( short )0x0248, ( short )0x03A0, ( short )0x0568, + ( short )0x0738, ( short )0x0870, ( short )0x0960, ( short )0x0A10, + ( short )0x0A40, ( short )0x0A28, ( short )0x09B8, ( short )0x08E8, + ( short )0x07E8, ( short )0x06E0, ( short )0x0588, ( short )0x0430, + ( short )0x0300, ( short )0x0260, ( short )0x01D0, ( short )0x0118, + ( short )0xFFB0, ( short )0xFE98, ( short )0xFE18, ( short )0xFDA0, + ( short )0xFD08, ( short )0xFCB8, ( short )0xFCF8, ( short )0xFD60, + ( short )0xFD90, ( short )0xFD90, ( short )0xFDD8, ( short )0xFE50, + ( short )0xFDA0, ( short )0xFCE0, ( short )0xFCC0, ( short )0xFCE8, + ( short )0xFCB0, ( short )0xFC60, ( short )0xFC70, ( short )0xFCB8, + ( short )0xFCE0, ( short )0xFD40, ( short )0xFDD8, ( short )0xFE68, + ( short )0xFF78, ( short )0x0068, ( short )0x0108, ( short )0x0278, + ( short )0x03A0, ( short )0x0420, ( short )0x0590, ( short )0x0708, + ( short )0x07B8, ( short )0x07D8, ( short )0x0808, ( short )0x0838, + ( short )0x07D8, ( short )0x06E8, ( short )0x0600, ( short )0x05B0, + ( short )0x0518, ( short )0x0410, ( short )0x02A0, ( short )0x0198, + ( short )0x00D0, ( short )0x00C8, ( short )0x00B0, ( short )0x0068, + ( short )0x00C0, ( short )0x0150, ( short )0x0180, ( short )0x0220, + ( short )0x02D8, ( short )0x0340, ( short )0x0360, ( short )0x0380, + ( short )0x0380, ( short )0x0338, ( short )0x02C8, ( short )0x02B8, + ( short )0x0280, ( short )0x0200, ( short )0x0100, ( short )0x0098, + ( short )0x0080, ( short )0x0020, ( short )0xFFF0, ( short )0x0000, + ( short )0x0020, ( short )0x0098, ( short )0x0120, ( short )0x0170, + ( short )0x0230, ( short )0x02F0, ( short )0x0350, ( short )0x0480, + ( short )0x05B8, ( short )0x0650, ( short )0x06A8, ( short )0x0738, + ( short )0x0798, ( short )0x07B0, ( short )0x07C0, ( short )0x0798, + ( short )0x0668, ( short )0x0598, ( short )0x0530, ( short )0x04C8, + ( short )0x0410, ( short )0x0350, ( short )0x0278, ( short )0x01D8, + ( short )0x0148, ( short )0x0080, ( short )0x0000, ( short )0xFFC0, + ( short )0xFFD8, ( short )0xFFA8, ( short )0xFF60, ( short )0xFF80, + ( short )0x0018, ( short )0x0070, ( short )0xFFE0, ( short )0xFF88, + ( short )0xFFC0, ( short )0xFF38, ( short )0xFE98, ( short )0xFE50, + ( short )0xFE10, ( short )0xFDD8, ( short )0xFD90, ( short )0xFD30, + ( short )0xFDB8, ( short )0xFE68, ( short )0xFE70, ( short )0xFE60, + ( short )0xFE70, ( short )0xFED0, ( short )0xFF90, ( short )0xFFE0, + ( short )0xFFF0, ( short )0x00A8, ( short )0x0168, ( short )0x01D0, + ( short )0x01F8, ( short )0x0210, ( short )0x0278, ( short )0x0268, + ( short )0x0208, ( short )0x0220, ( short )0x01F8, ( short )0x0198, + ( short )0x0158, ( short )0x0100, ( short )0x00C0, ( short )0x00A0, + ( short )0x0018, ( short )0xFF98, ( short )0xFF28, ( short )0xFEC0, + ( short )0xFE80, ( short )0xFE60, ( short )0xFD88, ( short )0xFCF0, + ( short )0xFCC8, ( short )0xFC70, ( short )0xFC10, ( short )0xFBC8, + ( short )0xFBB0, ( short )0xFBE8, ( short )0xFBE8, ( short )0xFB80, + ( short )0xFB88, ( short )0xFB40, ( short )0xFB18, ( short )0xFB20, + ( short )0xFAB8, ( short )0xFA50, ( short )0xFA50, ( short )0xFAB8, + ( short )0xFAF8, ( short )0xFB18, ( short )0xFBB0, ( short )0xFC88, + ( short )0xFD10, ( short )0xFD40, ( short )0xFD98, ( short )0xFE38, + ( short )0xFEE0, ( short )0xFEF8, ( short )0xFEF0, ( short )0xFF18, + ( short )0xFF18, ( short )0xFF18, ( short )0xFF68, ( short )0xFF98, + ( short )0xFF98, ( short )0xFFD0, ( short )0xFFF8, ( short )0x0048, + ( short )0x0038, ( short )0x0008, ( short )0x0008, ( short )0xFFE0, + ( short )0xFFB0, ( short )0xFFB8, ( short )0xFED0, ( short )0xFE18, + ( short )0xFE18, ( short )0xFDF0, ( short )0xFE38, ( short )0xFE90, + ( short )0xFE90, ( short )0xFDA8, ( short )0xFD48, ( short )0xFD70, + ( short )0xFD68, ( short )0xFD00, ( short )0xFCB8, ( short )0xFCB8, + ( short )0xFCF8, ( short )0xFD00, ( short )0xFC30, ( short )0xFBD0, + ( short )0xFC10, ( short )0xFC20, ( short )0xFBE0, ( short )0xFBA8, + ( short )0xFC30, ( short )0xFD00, ( short )0xFD50, ( short )0xFD90, + ( short )0xFE10, ( short )0xFEA8, ( short )0xFF40, ( short )0xFFA0, + ( short )0xFFD0, ( short )0xFFC8, ( short )0xFFC8, ( short )0xFFD8, + ( short )0xFFA0, ( short )0xFF98, ( short )0xFFB8, ( short )0x0050, + ( short )0x00B8, ( short )0x00B0, ( short )0x01B0, ( short )0x02E0, + ( short )0x0318, ( short )0x0330, ( short )0x02E0, ( short )0x02C8, + ( short )0x0278, ( short )0x0150, ( short )0x0050, ( short )0xFFC0, + ( short )0xFF88, ( short )0xFF18, ( short )0xFE90, ( short )0xFE40, + ( short )0xFE30, ( short )0xFDE8, ( short )0xFDD0, ( short )0xFD70, + ( short )0xFD48, ( short )0xFD10, ( short )0xFC98, ( short )0xFC38, + ( short )0xFC38, ( short )0xFC78, ( short )0xFC98, ( short )0xFCF0, + ( short )0xFDA8, ( short )0xFE48, ( short )0xFEC8, ( short )0xFF30, + ( short )0xFF98, ( short )0x0000, ( short )0x0050, ( short )0x0058, + ( short )0x00A8, ( short )0x00E8, ( short )0x00D0, ( short )0x0138, + ( short )0x01E0, ( short )0x0218, ( short )0x0208, ( short )0x0230, + ( short )0x0258, ( short )0x0248, ( short )0x02B0, ( short )0x0318, + ( short )0x0330, ( short )0x0358, ( short )0x0380, ( short )0x0378, + ( short )0x0408, ( short )0x0480, ( short )0x0460, ( short )0x03C8, + ( short )0x0318, ( short )0x02B0, ( short )0x01E8, ( short )0x00B8, + ( short )0xFFD8, ( short )0xFF30, ( short )0xFEC8, ( short )0xFE60, + ( short )0xFE60, ( short )0xFE78, ( short )0xFE78, ( short )0xFDC0, + ( short )0xFD70, ( short )0xFD50, ( short )0xFD08, ( short )0xFC88, + ( short )0xFC28, ( short )0xFC98, ( short )0xFD18, ( short )0xFD60, + ( short )0xFD60, ( short )0xFDD8, ( short )0xFE90, ( short )0xFEE8, + ( short )0xFF10, ( short )0xFF58, ( short )0xFF90, ( short )0xFFB8, + ( short )0xFFE0, ( short )0xFFF0, ( short )0xFFF0, ( short )0x00D0, + ( short )0x0190, ( short )0x01C8, ( short )0x0180, ( short )0x0188, + ( short )0x01B0, ( short )0x0238, ( short )0x0298, ( short )0x02B8, + ( short )0x0268, ( short )0x0258, ( short )0x0258, ( short )0x0230, + ( short )0x0228, ( short )0x0230, ( short )0x0258, ( short )0x0248, + ( short )0x01F8, ( short )0x0150, ( short )0x00C8, ( short )0x0058, + ( short )0x0058, ( short )0x0038, ( short )0x0000, ( short )0xFF50, + ( short )0xFF00, ( short )0xFEF8, ( short )0xFE80, ( short )0xFDB8, + ( short )0xFD70, ( short )0xFD00, ( short )0xFC90, ( short )0xFC40, + ( short )0xFC28, ( short )0xFC58, ( short )0xFC98, ( short )0xFD10, + ( short )0xFD78, ( short )0xFDE0, ( short )0xFE80, ( short )0xFF08, + ( short )0xFF60, ( short )0xFFD0, ( short )0x0030, ( short )0x0068, + ( short )0x0110, ( short )0x0198, ( short )0x01C0, ( short )0x0208, + ( short )0x0260, ( short )0x0280, ( short )0x0320, ( short )0x0390, + ( short )0x0398, ( short )0x0410, ( short )0x0488, ( short )0x04A0, + ( short )0x0448, ( short )0x0408, ( short )0x03E0, ( short )0x03C8, + ( short )0x0398, ( short )0x0350, ( short )0x0308, ( short )0x02C8, + ( short )0x0278, ( short )0x01D8, ( short )0x0148, ( short )0x00E8, + ( short )0x0040, ( short )0xFFA0, ( short )0xFF50, ( short )0xFDC0, + ( short )0xFC88, ( short )0xFC30, ( short )0xFB88, ( short )0xFAA8, + ( short )0xFA50, ( short )0xFA30, ( short )0xFA40, ( short )0xFA70, + ( short )0xFAB8, ( short )0xFAE0, ( short )0xFB28, ( short )0xFB58, + ( short )0xFB80, ( short )0xFBB0, ( short )0xFC00, ( short )0xFC80, + ( short )0xFCF0, ( short )0xFDB8, ( short )0xFE58, ( short )0xFED8, + ( short )0x0008, ( short )0x0100, ( short )0x0180, ( short )0x01D0, + ( short )0x0210, ( short )0x0248, ( short )0x0238, ( short )0x0200, + ( short )0x01D0, ( short )0x02D0, ( short )0x03A0, ( short )0x03D8, + ( short )0x03C0, ( short )0x03D8, ( short )0x03F8, ( short )0x0370, + ( short )0x02C0, ( short )0x0258, ( short )0x01B8, ( short )0x0120, + ( short )0x0090, ( short )0x0088, ( short )0x00A8, ( short )0x00A8, + ( short )0x0088, ( short )0x0068, ( short )0x0060, ( short )0xFFE0, + ( short )0xFF00, ( short )0xFE50, ( short )0xFDC8, ( short )0xFCF0, + ( short )0xFC30, ( short )0xFBB0, ( short )0xFBD8, ( short )0xFC20, + ( short )0xFC58, ( short )0xFC30, ( short )0xFC40, ( short )0xFC78, + ( short )0xFCC0, ( short )0xFCE8, ( short )0xFD10, ( short )0xFD48, + ( short )0xFD88, ( short )0xFDE8, ( short )0xFF10, ( short )0x0020, + ( short )0x0110, ( short )0x01B8, ( short )0x0248, ( short )0x02C0, + ( short )0x0358, ( short )0x03B8, ( short )0x03C8, ( short )0x0320, + ( short )0x0288, ( short )0x0280, ( short )0x0300, ( short )0x0340, + ( short )0x0320, ( short )0x0380, ( short )0x03F8, ( short )0x0418, + ( short )0x0378, ( short )0x02E0, ( short )0x0288, ( short )0x0280, + ( short )0x0238, ( short )0x01D0, ( short )0x0168, ( short )0x0138, + ( short )0x0110, ( short )0x0140, ( short )0x0148, ( short )0x0150, + ( short )0x00A8, ( short )0x0010, ( short )0xFFB0, ( short )0xFEB8, + ( short )0xFDE0, ( short )0xFD48, ( short )0xFCE8, ( short )0xFCA8, + ( short )0xFC78, ( short )0xFC48, ( short )0xFC50, ( short )0xFC70, + ( short )0xFCA8, ( short )0xFCE8, ( short )0xFD28, ( short )0xFDD0, + ( short )0xFE70, ( short )0xFED8, ( short )0x0040, ( short )0x0188, + ( short )0x0258, ( short )0x03C0, ( short )0x04F0, ( short )0x05B8, + ( short )0x0638, ( short )0x0670, ( short )0x0690, ( short )0x0708, + ( short )0x0708, ( short )0x06B8, ( short )0x0660, ( short )0x0650, + ( short )0x0630, ( short )0x05C8, ( short )0x0578, ( short )0x0548, + ( short )0x0508, ( short )0x0470, ( short )0x03D0, ( short )0x0350, + ( short )0x0278, ( short )0x01A0, ( short )0x00F8, ( short )0x00B0, + ( short )0x0078, ( short )0x0030, ( short )0xFFE8, ( short )0xFFC8, + ( short )0xFFB8, ( short )0xFED0, ( short )0xFE08, ( short )0xFD98, + ( short )0xFC70, ( short )0xFB60, ( short )0xFAA8, ( short )0xFA10, + ( short )0xF9B8, ( short )0xF980, ( short )0xF9A0, ( short )0xFA00, + ( short )0xFA68, ( short )0xFB90, ( short )0xFCB8, ( short )0xFD98, + ( short )0xFE68, ( short )0xFF18, ( short )0xFFC0, ( short )0x0078, + ( short )0x00F8, ( short )0x0218, ( short )0x0320, ( short )0x03C0, + ( short )0x0478, ( short )0x0510, ( short )0x0570, ( short )0x05D8, + ( short )0x05E0, ( short )0x05B8, ( short )0x0508, ( short )0x0468, + ( short )0x03E0, ( short )0x02F0, ( short )0x0218, ( short )0x0168, + ( short )0x00F0, ( short )0x0060, ( short )0xFFD0, ( short )0xFF58, + ( short )0xFEC0, ( short )0xFE48, ( short )0xFDB0, ( short )0xFD58, + ( short )0xFD38, ( short )0xFCD8, ( short )0xFC80, ( short )0xFC50, + ( short )0xFC08, ( short )0xFB48, ( short )0xFA98, ( short )0xF9F8, + ( short )0xF8F8, ( short )0xF810, ( short )0xF7F8, ( short )0xF818, + ( short )0xF848, ( short )0xF8E8, ( short )0xF9E0, ( short )0xFB08, + ( short )0xFC38, ( short )0xFD10, ( short )0xFDE8, ( short )0xFF10, + ( short )0xFFD0, ( short )0x0048, ( short )0x00E0, ( short )0x0160, + ( short )0x01B8, ( short )0x01C8, ( short )0x01E0, ( short )0x0200, + ( short )0x0228, ( short )0x0240, ( short )0x0240, ( short )0x0240, + ( short )0x0260, ( short )0x0280, ( short )0x0280, ( short )0x02F0, + ( short )0x0370, ( short )0x03C8, ( short )0x03C8, ( short )0x03A8, + ( short )0x03A0, ( short )0x02F8, ( short )0x0220, ( short )0x0150, + ( short )0x0098, ( short )0xFFE0, ( short )0xFF20, ( short )0xFEA0, + ( short )0xFE50, ( short )0xFE18, ( short )0xFD38, ( short )0xFC60, + ( short )0xFBE0, ( short )0xFAC8, ( short )0xF9A0, ( short )0xF8B8, + ( short )0xF830, ( short )0xF888, ( short )0xF8B8, ( short )0xF908, + ( short )0xFA80, ( short )0xFBF8, ( short )0xFD48, ( short )0xFEC8, + ( short )0x0040, ( short )0x01B0, ( short )0x0298, ( short )0x0338, + ( short )0x03C0, ( short )0x0470, ( short )0x0520, ( short )0x0588, + ( short )0x0610, ( short )0x0688, ( short )0x06C8, ( short )0x0670, + ( short )0x05E8, ( short )0x0578, ( short )0x0580, ( short )0x0578, + ( short )0x0528, ( short )0x0498, ( short )0x0408, ( short )0x0390, + ( short )0x03F8, ( short )0x0458, ( short )0x0488, ( short )0x0468, + ( short )0x0450, ( short )0x0458, ( short )0x03A8, ( short )0x02D0, + ( short )0x0210, ( short )0x0158, ( short )0x0088, ( short )0xFFA8, + ( short )0xFF00, ( short )0xFE88, ( short )0xFE30, ( short )0xFD88, + ( short )0xFCB8, ( short )0xFC28, ( short )0xFB30, ( short )0xF9F0, + ( short )0xF8E8, ( short )0xF890, ( short )0xF890, ( short )0xF8C0, + ( short )0xF978, ( short )0xFA78, ( short )0xFBE8, ( short )0xFD20, + ( short )0xFE28, ( short )0xFF60, ( short )0x00D8, ( short )0x0220, + ( short )0x02F8, ( short )0x0378, ( short )0x03E0, ( short )0x0438, + ( short )0x0488, ( short )0x0498, ( short )0x04A8, ( short )0x0480, + ( short )0x0440, ( short )0x03C0, ( short )0x02D8, ( short )0x01E8, + ( short )0x0140, ( short )0x00D8, ( short )0x0068, ( short )0xFFE0, + ( short )0x0068, ( short )0x0130, ( short )0x0228, ( short )0x0260, + ( short )0x0278, ( short )0x02D0, ( short )0x02D8, ( short )0x0290, + ( short )0x01E0, ( short )0x00D0, ( short )0xFFE0, ( short )0xFEF8, + ( short )0xFE08, ( short )0xFD28, ( short )0xFC88, ( short )0xFBE0, + ( short )0xFB60, ( short )0xFAD8, ( short )0xFA08, ( short )0xF978, + ( short )0xF8E8, ( short )0xF8B0, ( short )0xF8B0, ( short )0xF8D0, + ( short )0xF9D0, ( short )0xFAF8, ( short )0xFC18, ( short )0xFDB0, + ( short )0xFF38, ( short )0x00A0, ( short )0x01F8, ( short )0x02F8, + ( short )0x03C0, ( short )0x0460, ( short )0x04B8, ( short )0x04C8, + ( short )0x04C8, ( short )0x04C0, ( short )0x0498, ( short )0x0490, + ( short )0x0478, ( short )0x0448, ( short )0x0420, ( short )0x03F8, + ( short )0x0328, ( short )0x0238, ( short )0x01B0, ( short )0x0170, + ( short )0x0128, ( short )0x0090, ( short )0x00E8, ( short )0x01B8, + ( short )0x02B8, ( short )0x0280, ( short )0x0218, ( short )0x0218, + ( short )0x01F0, ( short )0x0148, ( short )0x0000, ( short )0xFEC0, + ( short )0xFE08, ( short )0xFD70, ( short )0xFCA0, ( short )0xFBF0, + ( short )0xFBC0, ( short )0xFBA0, ( short )0xFB80, ( short )0xFB18, + ( short )0xFB28, ( short )0xFB98, ( short )0xFBC0, ( short )0xFBD0, + ( short )0xFC08, ( short )0xFC78, ( short )0xFDC8, ( short )0xFEC8, + ( short )0xFF78, ( short )0x00D0, ( short )0x0238, ( short )0x0360, + ( short )0x0398, ( short )0x0360, ( short )0x0368, ( short )0x0380, + ( short )0x0318, ( short )0x0250, ( short )0x0208, ( short )0x0220, + ( short )0x0218, ( short )0x01F0, ( short )0x01C8, ( short )0x0210, + ( short )0x0270, ( short )0x0270, ( short )0x0240, ( short )0x0290, + ( short )0x0310, ( short )0x0360, ( short )0x0340, ( short )0x0310, + ( short )0x0318, ( short )0x0320, ( short )0x02D8, ( short )0x0240, + ( short )0x0158, ( short )0x00A0, ( short )0x0008, ( short )0xFF30, + ( short )0xFE50, ( short )0xFDA8, ( short )0xFD28, ( short )0xFCC8, + ( short )0xFC60, ( short )0xFBA8, ( short )0xFB40, ( short )0xFB10, + ( short )0xFB18, ( short )0xFB28, ( short )0xFB48, ( short )0xFB68, + ( short )0xFBA8, ( short )0xFBF8, ( short )0xFCB8, ( short )0xFD78, + ( short )0xFE00, ( short )0xFE88, ( short )0xFF30, ( short )0xFF98, + ( short )0xFFC8, ( short )0xFFE8, ( short )0x0050, ( short )0x00B0, + ( short )0x00E0, ( short )0x0040, ( short )0xFF68, ( short )0xFED8, + ( short )0xFEE8, ( short )0xFEE0, ( short )0xFE90, ( short )0xFEA8, + ( short )0xFF88, ( short )0x0080, ( short )0x0188, ( short )0x0208, + ( short )0x0290, ( short )0x0390, ( short )0x0438, ( short )0x0450, + ( short )0x0428, ( short )0x03F8, ( short )0x03E0, ( short )0x0388, + ( short )0x02E0, ( short )0x0240, ( short )0x0190, ( short )0x00D0, + ( short )0x0000, ( short )0x0000, ( short )0x0018, ( short )0x00FF, + ( short )0x0068, ( short )0x00FE, ( short )0x00F8, ( short )0x00FD +}; + +gsm_byte gsm_dec_gsmdata[] = { + 0xD5, 0x1F, 0x74, 0x21, 0xA0, 0x50, 0x40, 0xC9, 0x24, 0x7B, 0xFA, 0x6B, + 0x52, 0xE0, 0xB6, 0xD6, 0x8E, 0xB9, 0x2B, 0xAE, 0xE0, 0x8B, 0x23, 0x52, + 0x3B, 0x13, 0x86, 0xE0, 0x14, 0x4A, 0x41, 0x44, 0x32, 0xD3, 0xA1, 0x83, + 0xA1, 0x1D, 0xA6, 0x80, 0xBA, 0xD2, 0x96, 0x26, 0xFB, 0x84, 0x80, 0x6D, + 0x9C, 0x25, 0x1D, 0x9B, 0xAA, 0xC0, 0xBB, 0x4C, 0x95, 0xB9, 0x53, 0xAE, + 0xA0, 0xB6, 0xE4, 0x46, 0x37, 0x1B, 0xD4, 0xA5, 0x7B, 0x1D, 0x22, 0x97, + 0x00, 0xBA, 0xA5, 0x6D, 0xD2, 0xA1, 0x7E, 0xC0, 0xB9, 0x25, 0xD2, 0xB4, + 0x94, 0x9E, 0xE0, 0x3E, 0xDE, 0xED, 0xD6, 0xD2, 0xE2, 0xC0, 0xD7, 0x5D, + 0x8D, 0x59, 0xAC, 0xD3, 0xE4, 0x83, 0x95, 0x59, 0xC0, 0xA1, 0x48, 0xD2, + 0x66, 0xC7, 0x2C, 0x9E, 0xA0, 0x2A, 0xD3, 0xEE, 0x45, 0x1C, 0x80, 0xE0, + 0x6B, 0x34, 0x8C, 0x4B, 0x29, 0xCB, 0x00, 0xBA, 0xF6, 0x0D, 0x26, 0x9A, + 0xD3, 0xA4, 0x82, 0x9D, 0x63, 0x7A, 0xC0, 0x67, 0x24, 0xBA, 0xD6, 0x7C, + 0xC2, 0xC0, 0x37, 0x20, 0x4F, 0x10, 0xE0, 0xC7, 0x80, 0x6A, 0x77, 0x63, + 0xBE, 0x6B, 0x5A, 0xC0, 0xB5, 0x34, 0xD1, 0x34, 0x9C, 0xD4, 0xE8, 0x56, + 0xB2, 0x58, 0x5F, 0x00, 0xB7, 0xAF, 0x92, 0x12, 0x90, 0xD5, 0xA4, 0x39, + 0x23, 0x4E, 0x46, 0x87, 0x51, 0xAC, 0xD8, 0xDB, 0x6D, 0xCB, 0x17, 0x50, + 0x89, 0x7B, 0x44, 0x28, 0x03, 0x6B, 0xD5, 0xA9, 0x36, 0x36, 0xD9, 0x6B, + 0xA8, 0x93, 0x3A, 0x96, 0xEE, 0xFF, 0x67, 0x8B, 0x36, 0xDA, 0x09, 0xB4, + 0x99, 0x67, 0x2B, 0x88, 0xE4, 0xB5, 0xA5, 0xDA, 0x65, 0x47, 0xDA, 0x1E, + 0x96, 0xFA, 0xEC, 0xD5, 0xA9, 0x45, 0x63, 0x1A, 0xCB, 0xC9, 0x48, 0x9D, + 0x83, 0x5F, 0x6F, 0xCB, 0x08, 0x1B, 0x97, 0xC9, 0x18, 0x0A, 0x63, 0xCB, + 0xA6, 0xE1, 0x84, 0xF5, 0x62, 0x61, 0x6A, 0x84, 0xDC, 0xB6, 0x37, 0x9E, + 0xD6, 0xAB, 0x3C, 0x53, 0x93, 0xC1, 0x2A, 0xAA, 0x81, 0x8D, 0x6B, 0x65, + 0x60, 0xA8, 0xFB, 0x2E, 0x22, 0x59, 0x74, 0x61, 0xA6, 0x5D, 0x73, 0x94, + 0xF8, 0xE4, 0xC1, 0x46, 0x26, 0x5E, 0x8A, 0x86, 0xED, 0xD4, 0xA6, 0x2D, + 0x57, 0x6B, 0xBE, 0xE8, 0x58, 0xDA, 0x3D, 0x98, 0x99, 0xBE, 0xA8, 0xC2, + 0xDB, 0x6A, 0x2E, 0x51, 0x62, 0xE5, 0x80, 0x58, 0x76, 0xB8, 0xE4, 0x6C, + 0x84, 0xCA, 0x98, 0x06, 0x0B, 0xFC, 0xD2, 0x66, 0x7C, 0x62, 0x3A, 0x5B, + 0xC5, 0xDF, 0x7D, 0x75, 0x49, 0x1E, 0x52, 0xC7, 0x55, 0xF7, 0x84, 0xA6, + 0xDA, 0x5D, 0x43, 0x26, 0x85, 0x98, 0xD8, 0x8F, 0xB6, 0xC5, 0x28, 0xEB, + 0x3E, 0x75, 0x04, 0xD2, 0x27, 0xBA, 0x2A, 0x2B, 0xB7, 0x03, 0x13, 0x45, + 0x35, 0x1B, 0x78, 0x5F, 0xC3, 0xBA, 0xDB, 0xAE, 0x27, 0xC2, 0x5E, 0xA4, + 0x50, 0x8C, 0x8A, 0xBB, 0x4F, 0x60, 0xC3, 0xEE, 0x41, 0x46, 0x4A, 0xDF, + 0xD2, 0x27, 0xB2, 0xAD, 0xEB, 0x5F, 0x43, 0x4C, 0x6A, 0x09, 0x2A, 0xCC, + 0xB7, 0x47, 0x2A, 0xB9, 0x91, 0xB6, 0xD4, 0x5B, 0x25, 0x58, 0xD8, 0xFD, + 0x46, 0x95, 0x5A, 0xC3, 0x27, 0x5B, 0x3F, 0xFB, 0x12, 0xD2, 0x26, 0xC3, + 0xA9, 0xA1, 0xB6, 0xA2, 0xCB, 0x1B, 0xD0, 0x73, 0xE4, 0xBA, 0xA1, 0xE9, + 0x05, 0xBE, 0x79, 0x23, 0xA4, 0xC2, 0x3A, 0x4B, 0x11, 0xE5, 0x68, 0xC4, + 0xC1, 0xBA, 0xC1, 0xCC, 0x8B, 0x02, 0xD2, 0x63, 0x6C, 0xEE, 0x19, 0x5E, + 0xE1, 0xB6, 0x4C, 0x1A, 0xB4, 0x5E, 0xF0, 0xC2, 0x27, 0x20, 0x55, 0xBD, + 0x6D, 0x64, 0xE1, 0xC7, 0x45, 0xA9, 0x65, 0x6D, 0x7D, 0x42, 0x56, 0xD8, + 0xB2, 0xB6, 0xEC, 0xD3, 0x61, 0x5B, 0x62, 0x61, 0x60, 0xA1, 0x5B, 0xD6, + 0x15, 0x29, 0x09, 0x6C, 0xA1, 0x3E, 0xAD, 0x65, 0x34, 0xC3, 0xC0, 0xC1, + 0x22, 0x6D, 0x4C, 0x57, 0x10, 0xDB, 0x41, 0xD2, 0xE1, 0x77, 0x64, 0xF7, + 0xD3, 0x21, 0x73, 0xA9, 0x29, 0x58, 0xC1, 0xA1, 0x5A, 0x52, 0xB7, 0x32, + 0x64, 0xC1, 0x67, 0x42, 0x74, 0x2C, 0xDC, 0x61, 0x61, 0x65, 0x8B, 0xCB, + 0x04, 0xE5, 0x60, 0xC1, 0xC9, 0x5E, 0x8E, 0x36, 0x83, 0xD2, 0xA2, 0x83, + 0xA9, 0xD9, 0xCD, 0x21, 0xB9, 0x25, 0xCD, 0xE6, 0x1D, 0x60, 0xA1, 0xB4, + 0xAA, 0x8F, 0xBA, 0x75, 0xC3, 0x01, 0x0B, 0x3B, 0x51, 0xDB, 0xEC, 0x62, + 0xE1, 0x38, 0xCD, 0x40, 0x3B, 0xD3, 0xD2, 0x26, 0x94, 0x29, 0xD2, 0x61, + 0x21, 0x6B, 0x4A, 0x8D, 0x24, 0xB5, 0xBB, 0x21, 0x12, 0xA5, 0x99, 0xA5, + 0x1A, 0xCA, 0xA1, 0xEF, 0x5D, 0xAA, 0xAE, 0xD3, 0x64, 0xE1, 0xA3, 0x6B, + 0xAE, 0x35, 0x39, 0xD2, 0x66, 0x73, 0xB6, 0x90, 0xC6, 0xC1, 0x32, 0xD1, + 0xBA, 0xC9, 0x25, 0x65, 0x81, 0xA8, 0xD2, 0xB1, 0xE7, 0x18, 0xBE, 0xC0, + 0xFC, 0xE4, 0x85, 0xB5, 0x06, 0xB4, 0x81, 0x35, 0x46, 0xB6, 0xC8, 0x9B +}; + +#endif /* GSM_DEC_DATA_H */ diff --git a/baseline/source/gsm_dec/gsm.h b/baseline/source/gsm_dec/gsm.h new file mode 100644 index 0000000..1d89577 --- /dev/null +++ b/baseline/source/gsm_dec/gsm.h @@ -0,0 +1,14 @@ +#ifndef GSM_DEC_GSM_H +#define GSM_DEC_GSM_H + +/* + Interface +*/ +typedef struct gsm_state *gsm; +typedef short gsm_signal; /* signed 16 bit */ +typedef unsigned char gsm_byte; +typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ + +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +#endif /* GSM_DEC_GSM_H */ diff --git a/baseline/source/gsm_dec/gsm_dec.c b/baseline/source/gsm_dec/gsm_dec.c new file mode 100644 index 0000000..7a0a1bd --- /dev/null +++ b/baseline/source/gsm_dec/gsm_dec.c @@ -0,0 +1,764 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: gsm_dec + + Author: Jutta Degener and Carsten Bormann, + Technische Universitaet Berlin + + Function: Decoding of GSM data + + Source: included in MediaBench/gsm + + Original name: gsm_decode + + Changes: no major functional changes + + License: see the accompanying COPYRIGHT file + +*/ + + +#include "../extra.h" +#include "gsm.h" +#include "add.h" +#include "data.h" +#include "private.h" + +#define SAMPLES 20 + +/* + Forward declaration of global variables +*/ + +struct gsm_state gsm_dec_state; +gsm gsm_dec_state_ptr; +volatile int gsm_dec_result; + +/* + Forward declaration of functions +*/ + +extern word gsm_dec_sub( word a, word b ); +extern word gsm_dec_asl( word a, int n ); +void gsm_dec_Decoding_of_the_coded_Log_Area_Ratios( + word *LARc, /* coded log area ratio [0..7] IN */ + word *LARpp ); /* out: decoded .. */ + +void gsm_dec_Coefficients_0_12( word *LARpp_j_1, word *LARpp_j, word *LARp ); + +void gsm_dec_LARp_to_rp( word *LARp ); /* [0..7] IN/OUT */ + +extern int gsm_dec_decode( gsm, gsm_byte *, gsm_signal * ); + +extern void gsm_dec_Decoder( struct gsm_state *S, + word *LARcr, /* [0..7] IN */ + word *Ncr, /* [0..3] IN */ + word *bcr, /* [0..3] IN */ + word *Mcr, /* [0..3] IN */ + word *xmaxcr, /* [0..3] IN */ + word *xMcr, /* [0..13*4] IN */ + word *s ); /* [0..159] OUT */ + +extern void gsm_dec_Long_Term_Synthesis_Filtering( + struct gsm_state *S, word Ncr, word bcr, + word *erp, /* [0..39] IN */ + word *drp ); /* [-120..-1] IN, [0..40] OUT */ + +void gsm_dec_RPE_Decoding( word xmaxcr, word Mcr, + word *xMcr, /* [0..12], 3 bits IN */ + word *erp ); /* [0..39] OUT */ + +void gsm_dec_RPE_grid_positioning( word Mc, /* grid position IN */ + word *xMp, /* [0..12] IN */ + word *ep /* [0..39] OUT */ + ); + +void gsm_dec_APCM_inverse_quantization( word *xMc, /* [0..12] IN */ + word mant, word exp, + word *xMp ); /* [0..12] OUT */ + +extern word gsm_dec_asr( word a, int n ); + +void gsm_dec_APCM_quantization_xmaxc_to_exp_mant( + word xmaxc, /* IN */ + word *exp_out, /* OUT */ + word *mant_out ); /* OUT */ + +void gsm_dec_Postprocessing( struct gsm_state *S, word *s ); + +void gsm_dec_Coefficients_13_26( word *LARpp_j_1, word *LARpp_j, + word *LARp ); + +void gsm_dec_Coefficients_40_159( word *LARpp_j, word *LARp ); + +void gsm_dec_Short_term_synthesis_filtering( struct gsm_state *S, + word *rrp, /* [0..7] IN */ + int k, /* k_end - k_start */ + word *wt, /* [0..k-1] IN */ + word *sr /* [0..k-1] OUT */ + ); + +void gsm_dec_Short_Term_Synthesis_Filter( + struct gsm_state *S, word *LARcr, /* received log area ratios [0..7] IN */ + word *wt, /* received d [0..159] IN */ + word *s /* signal s [0..159] OUT */ +); + +void gsm_dec_Coefficients_27_39( word *LARpp_j_1, word *LARpp_j, word *LARp ); + +gsm gsm_dec_create( void ); +void gsm_dec_init( void ); +void gsm_dec_main( void ); +//int main( void ); + +/* add.c */ + +word gsm_dec_sub( word a, word b ) +{ + longword diff = ( longword )a - ( longword )b; + return saturate( diff ); +} + +word gsm_dec_asl( word a, int n ) +{ + if ( n >= 16 ) + return 0; + if ( n <= -16 ) + return -( a < 0 ); + if ( n < 0 ) + return gsm_dec_asr( a, -n ); + return a << n; +} + +/* short_term.c */ +/* + SHORT TERM ANALYSIS FILTERING SECTION +*/ + +/* 4.2.8 */ + +void gsm_dec_Decoding_of_the_coded_Log_Area_Ratios( + word *LARc, /* coded log area ratio [0..7] IN */ + word *LARpp ) /* out: decoded .. */ +{ + word temp1 /* for STEP */; + long ltmp; /* for GSM_ADD */ + + /* This procedure requires for efficient implementation + two tables. + + INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) + MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] + */ + + /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { + + temp1 = GSM_ADD( *LARc, *MIC ) << 10; + temp2 = *B << 1; + temp1 = GSM_SUB( temp1, temp2 ); + + temp1 = GSM_MULT_R( *INVA, temp1 ); + LARpp = GSM_ADD( temp1, temp1 ); + } + */ + +#undef STEP +#define STEP(B, MIC, INVA) \ + temp1 = GSM_ADD(*LARc++, MIC) << 10; \ + temp1 = GSM_SUB(temp1, B << 1); \ + temp1 = GSM_MULT_R(INVA, temp1); \ + *LARpp++ = GSM_ADD(temp1, temp1); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( 2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( 1792, -8, 17476 ); + STEP( 341, -4, 31454 ); + STEP( 1144, -4, 29708 ); + + /* NOTE: the addition of *MIC is used to restore the sign of *LARc. + */ +} + +/* 4.2.9 */ +/* Computation of the quantized reflection coefficients +*/ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] +*/ + +/* + Within each frame of 160 analyzed speech samples the short term + analysis and synthesis filters operate with four different sets of + coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) + and the actual set of decoded LARs (LARpp(j)) + + (Initial value: LARpp(j-1)[1..8] = 0.) +*/ + + +void gsm_dec_Coefficients_0_12( word *LARpp_j_1, word *LARpp_j, word *LARp ) +{ + int i; + longword ltmp; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++ ) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ) ); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1 ) ); + } +} + +/* 4.2.9.2 */ + +void gsm_dec_LARp_to_rp( word *LARp ) /* [0..7] IN/OUT */ +/* + The input of this procedure is the interpolated LARp[0..7] array. + The reflection coefficients, rp[i], are used in the analysis + filter and in the synthesis filter. +*/ +{ + int i; + word temp; + longword ltmp; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARp++ ) { + + /* temp = GSM_ABS( *LARp ); + + if (temp < 11059) temp <<= 1; + else if (temp < 20070) temp += 11059; + else temp = GSM_ADD( temp >> 2, 26112 ); + + * *LARp = *LARp < 0 ? -temp : temp; + */ + + if ( *LARp < 0 ) { + temp = *LARp == MIN_WORD ? MAX_WORD : -( *LARp ); + *LARp = -( ( temp < 11059 ) ? temp << 1 + : ( ( temp < 20070 ) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 ) ) ); + } else { + temp = *LARp; + *LARp = ( temp < 11059 ) + ? temp << 1 + : ( ( temp < 20070 ) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 ) ); + } + } +} + +void gsm_dec_Decoder( struct gsm_state *S, + word *LARcr, /* [0..7] IN */ + word *Ncr, /* [0..3] IN */ + word *bcr, /* [0..3] IN */ + word *Mcr, /* [0..3] IN */ + word *xmaxcr, /* [0..3] IN */ + word *xMcr, /* [0..13*4] IN */ + word *s ) /* [0..159] OUT */ +{ + int j, k; + word erp[40], wt[160]; + word *drp = S->dp0 + 120; + + _Pragma( "loopbound min 4 max 4" ) + for ( j = 0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13 ) { + + gsm_dec_RPE_Decoding( *xmaxcr, *Mcr, xMcr, erp ); + gsm_dec_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); + + _Pragma( "loopbound min 40 max 40" ) + for ( k = 0; k <= 39; k++ ) + wt[j * 40 + k] = drp[k]; + } + + gsm_dec_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); + gsm_dec_Postprocessing( S, s ); +} + +/* 4.3.2 */ +void gsm_dec_Long_Term_Synthesis_Filtering( + struct gsm_state *S, + word Ncr, word bcr, word *erp, /* [0..39] IN */ + word *drp /* [-120..-1] IN, [0..40] OUT */ +) +/* + This procedure uses the bcr and Ncr parameter to realize the + long term synthesis filtering. The decoding of bcr needs + table 4.3b. +*/ +{ + longword ltmp; /* for ADD */ + int k; + word brp, drpp, Nr; + + /* Check the limits of Nr. + */ + Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; + S->nrp = Nr; + + /* Decoding of the LTP gain bcr + */ + brp = gsm_dec_QLB[bcr]; + + /* Computation of the reconstructed short term residual + signal drp[0..39] + */ + + _Pragma( "loopbound min 40 max 40" ) + for ( k = 0; k <= 39; k++ ) { + drpp = GSM_MULT_R( brp, drp[k - Nr] ); + drp[k] = GSM_ADD( erp[k], drpp ); + } + + /* + Update of the reconstructed short term residual signal + drp[ -1..-120 ] + */ + + _Pragma( "loopbound min 120 max 120" ) + for ( k = 0; k <= 119; k++ ) + drp[-120 + k] = drp[-80 + k]; +} + +void gsm_dec_RPE_Decoding( word xmaxcr, word Mcr, + word *xMcr, /* [0..12], 3 bits IN */ + word *erp ) /* [0..39] OUT */ +{ + word exp, mant; + word xMp[13]; + + gsm_dec_APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); + gsm_dec_APCM_inverse_quantization( xMcr, mant, exp, xMp ); + gsm_dec_RPE_grid_positioning( Mcr, xMp, erp ); +} + +/* 4.2.17 */ +void gsm_dec_RPE_grid_positioning( + word Mc, /* grid position IN */ + word *xMp, /* [0..12] IN */ + word *ep /* [0..39] OUT */ ) +/* + This procedure computes the reconstructed long term residual signal + ep[0..39] for the LTP analysis filter. The inputs are the Mc + which is the grid position selection and the xMp[0..12] decoded + RPE samples which are upsampled by a factor of 3 by inserting zero + values. +*/ +{ + int i = 13; + + /* Rewritten Duff's device for WCET analysis! */ + switch ( Mc ) { + case 3: + *ep++ = 0; + case 2: + *ep++ = 0; + case 1: + *ep++ = 0; + case 0: + *ep++ = *xMp++; + i--; + } + + _Pragma( "loopbound min 12 max 12" ) + do { + *ep++ = 0; + *ep++ = 0; + *ep++ = *xMp++; + } while ( --i ); + + _Pragma( "loopbound min 0 max 2" ) + while ( ++Mc < 4 ) + *ep++ = 0; + +} + +/* 4.2.16 */ +void gsm_dec_APCM_inverse_quantization( word *xMc, /* [0..12] IN */ + word mant, + word exp, + word *xMp ) /* [0..12] OUT */ +/* + This part is for decoding the RPE sequence of coded xMc[0..12] + samples to obtain the xMp[0..12] array. Table 4.6 is used to get + the mantissa of xmaxc (FAC[0..7]). +*/ +{ + int i; + word temp, temp1, temp2, temp3; + longword ltmp; + + temp1 = gsm_dec_FAC[mant]; /* see 4.2-15 for mant */ + temp2 = gsm_dec_sub( 6, exp ); /* see 4.2-15 for exp */ + temp3 = gsm_dec_asl( 1, gsm_dec_sub( temp2, 1 ) ); + + _Pragma( "loopbound min 13 max 13" ) + for ( i = 13; i--; ) { + + /* temp = gsm_sub( *xMc++ << 1, 7 ); */ + temp = ( *xMc++ << 1 ) - 7; /* restore sign */ + + temp <<= 12; /* 16 bit signed */ + temp = GSM_MULT_R( temp1, temp ); + temp = GSM_ADD( temp, temp3 ); + *xMp++ = gsm_dec_asr( temp, temp2 ); + } +} + +/* + 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION +*/ +word gsm_dec_asr( word a, int n ) +{ + if ( n >= 16 ) + return -( a < 0 ); + if ( n <= -16 ) + return 0; + if ( n < 0 ) + return a << -n; + + return a >> n; +} + +/* rpe.c */ +/* 4.12.15 */ +void gsm_dec_APCM_quantization_xmaxc_to_exp_mant( word xmaxc, /* IN */ + word *exp_out, /* OUT */ + word *mant_out ) /* OUT */ +{ + word exp, mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + exp = 0; + if ( xmaxc > 15 ) + exp = SASR( xmaxc, 3 ) - 1; + mant = xmaxc - ( exp << 3 ); + + if ( mant == 0 ) { + exp = -4; + mant = 7; + } else { + _Pragma( "loopbound min 0 max 3" ) + while ( mant <= 7 ) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; +} + +/* decode.c */ +/* + 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER +*/ +void gsm_dec_Postprocessing( struct gsm_state *S, word *s ) +{ + int k; + word msr = S->msr; + longword ltmp; /* for GSM_ADD */ + word tmp; + + _Pragma( "loopbound min 159 max 159" ) + for ( k = 160; --k; ++s ) { + tmp = GSM_MULT_R( msr, 28180 ); + msr = GSM_ADD( *s, tmp ); /* Deemphasis */ + *s = GSM_ADD( msr, msr ) & 0xFFF8; /* Truncation & Upscaling */ + } + S->msr = msr; +} + +void gsm_dec_Coefficients_13_26( word *LARpp_j_1, word *LARpp_j, word *LARp ) +{ + int i; + longword ltmp; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++ ) + *LARp = GSM_ADD( SASR( *LARpp_j_1, 1 ), SASR( *LARpp_j, 1 ) ); +} + +void gsm_dec_Coefficients_40_159( word *LARpp_j, word *LARp ) +{ + int i; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARp++, LARpp_j++ ) + *LARp = *LARpp_j; +} + +void gsm_dec_Short_term_synthesis_filtering( struct gsm_state *S, + word *rrp, /* [0..7] IN */ + int k, /* k_end - k_start */ + word *wt, /* [0..k-1] IN */ + word *sr ) /* [0..k-1] OUT */ +{ + word *v = S->v; + int i; + word sri, tmp1, tmp2; + longword ltmp; /* for GSM_ADD & GSM_SUB */ + + _Pragma( "loopbound min 12 max 118" ) + while ( --k ) { + sri = *wt++; + _Pragma( "loopbound min 8 max 8" ) + for ( i = 8; i--; ) { + + /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); + */ + tmp1 = rrp[i]; + tmp2 = v[i]; + tmp2 = + ( tmp1 == MIN_WORD && tmp2 == MIN_WORD + ? MAX_WORD + : 0x0FFFF & ( ( ( longword )tmp1 * ( longword )tmp2 + 16384 ) >> 15 ) ); + + sri = GSM_SUB( sri, tmp2 ); + + /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); + */ + tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD + ? MAX_WORD + : 0x0FFFF & ( ( ( longword )tmp1 * ( longword )sri + 16384 ) >> 15 ) ); + + v[i + 1] = GSM_ADD( v[i], tmp1 ); + } + *sr++ = v[0] = sri; + } +} + +void gsm_dec_Short_Term_Synthesis_Filter( + struct gsm_state *S, + word *LARcr, /* received log area ratios [0..7] IN */ + word *wt, /* received d [0..159] IN */ + word *s /* signal s [0..159] OUT */ +) +{ + word *LARpp_j = S->LARpp[S->j]; + word *LARpp_j_1 = S->LARpp[S->j ^= 1]; + + word LARp[8]; + + gsm_dec_Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); + + gsm_dec_Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 13, wt, s ); + + gsm_dec_Coefficients_13_26( LARpp_j_1, LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 14, wt + 13, s + 13 ); + + gsm_dec_Coefficients_27_39( LARpp_j_1, LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 13, wt + 27, s + 27 ); + + gsm_dec_Coefficients_40_159( LARpp_j, LARp ); + gsm_dec_LARp_to_rp( LARp ); + gsm_dec_Short_term_synthesis_filtering( S, LARp, 120, wt + 40, s + 40 ); +} + +void gsm_dec_Coefficients_27_39( word *LARpp_j_1, word *LARpp_j, word *LARp ) +{ + int i; + longword ltmp; + + _Pragma( "loopbound min 8 max 8" ) + for ( i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++ ) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ) ); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ) ); + } +} + +/* + Initialization- and return-value-related functions +*/ + +gsm gsm_dec_create( void ) +{ + unsigned int i; + gsm r; + volatile char x = 0; + + r = &gsm_dec_state; + + _Pragma( "loopbound min 648 max 648" ) + for ( i = 0; i < sizeof( *r ); i++ ) + ( ( char * )r )[i] = 0 + x; + + r->nrp = 40; + + return r; +} + +void gsm_dec_init( void ) +{ + gsm_dec_state_ptr = gsm_dec_create(); +} + +int gsm_dec_return( void ) +{ + return gsm_dec_result; +} + +/* + Main functions +*/ + +/* gsm_decode.c */ +int gsm_dec_decode( gsm s, gsm_byte *c, gsm_signal *target ) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13 * 4]; + + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if ( ( ( *c >> 4 ) & 0x0F ) != GSM_MAGIC ) + return -1; + + LARc[0] = ( *c++ & 0xF ) << 2; /* 1 */ + LARc[0] |= ( *c >> 6 ) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = ( *c >> 3 ) & 0x1F; + LARc[3] = ( *c++ & 0x7 ) << 2; + LARc[3] |= ( *c >> 6 ) & 0x3; + LARc[4] = ( *c >> 2 ) & 0xF; + LARc[5] = ( *c++ & 0x3 ) << 2; + LARc[5] |= ( *c >> 6 ) & 0x3; + LARc[6] = ( *c >> 3 ) & 0x7; + LARc[7] = *c++ & 0x7; + Nc[0] = ( *c >> 1 ) & 0x7F; + bc[0] = ( *c++ & 0x1 ) << 1; + bc[0] |= ( *c >> 7 ) & 0x1; + Mc[0] = ( *c >> 5 ) & 0x3; + xmaxc[0] = ( *c++ & 0x1F ) << 1; + xmaxc[0] |= ( *c >> 7 ) & 0x1; + xmc[0] = ( *c >> 4 ) & 0x7; + xmc[1] = ( *c >> 1 ) & 0x7; + xmc[2] = ( *c++ & 0x1 ) << 2; + xmc[2] |= ( *c >> 6 ) & 0x3; + xmc[3] = ( *c >> 3 ) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = ( *c >> 5 ) & 0x7; + xmc[6] = ( *c >> 2 ) & 0x7; + xmc[7] = ( *c++ & 0x3 ) << 1; /* 10 */ + xmc[7] |= ( *c >> 7 ) & 0x1; + xmc[8] = ( *c >> 4 ) & 0x7; + xmc[9] = ( *c >> 1 ) & 0x7; + xmc[10] = ( *c++ & 0x1 ) << 2; + xmc[10] |= ( *c >> 6 ) & 0x3; + xmc[11] = ( *c >> 3 ) & 0x7; + xmc[12] = *c++ & 0x7; + Nc[1] = ( *c >> 1 ) & 0x7F; + bc[1] = ( *c++ & 0x1 ) << 1; + bc[1] |= ( *c >> 7 ) & 0x1; + Mc[1] = ( *c >> 5 ) & 0x3; + xmaxc[1] = ( *c++ & 0x1F ) << 1; + xmaxc[1] |= ( *c >> 7 ) & 0x1; + xmc[13] = ( *c >> 4 ) & 0x7; + xmc[14] = ( *c >> 1 ) & 0x7; + xmc[15] = ( *c++ & 0x1 ) << 2; + xmc[15] |= ( *c >> 6 ) & 0x3; + xmc[16] = ( *c >> 3 ) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = ( *c >> 5 ) & 0x7; + xmc[19] = ( *c >> 2 ) & 0x7; + xmc[20] = ( *c++ & 0x3 ) << 1; + xmc[20] |= ( *c >> 7 ) & 0x1; + xmc[21] = ( *c >> 4 ) & 0x7; + xmc[22] = ( *c >> 1 ) & 0x7; + xmc[23] = ( *c++ & 0x1 ) << 2; + xmc[23] |= ( *c >> 6 ) & 0x3; + xmc[24] = ( *c >> 3 ) & 0x7; + xmc[25] = *c++ & 0x7; + Nc[2] = ( *c >> 1 ) & 0x7F; + bc[2] = ( *c++ & 0x1 ) << 1; /* 20 */ + bc[2] |= ( *c >> 7 ) & 0x1; + Mc[2] = ( *c >> 5 ) & 0x3; + xmaxc[2] = ( *c++ & 0x1F ) << 1; + xmaxc[2] |= ( *c >> 7 ) & 0x1; + xmc[26] = ( *c >> 4 ) & 0x7; + xmc[27] = ( *c >> 1 ) & 0x7; + xmc[28] = ( *c++ & 0x1 ) << 2; + xmc[28] |= ( *c >> 6 ) & 0x3; + xmc[29] = ( *c >> 3 ) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = ( *c >> 5 ) & 0x7; + xmc[32] = ( *c >> 2 ) & 0x7; + xmc[33] = ( *c++ & 0x3 ) << 1; + xmc[33] |= ( *c >> 7 ) & 0x1; + xmc[34] = ( *c >> 4 ) & 0x7; + xmc[35] = ( *c >> 1 ) & 0x7; + xmc[36] = ( *c++ & 0x1 ) << 2; + xmc[36] |= ( *c >> 6 ) & 0x3; + xmc[37] = ( *c >> 3 ) & 0x7; + xmc[38] = *c++ & 0x7; + Nc[3] = ( *c >> 1 ) & 0x7F; + bc[3] = ( *c++ & 0x1 ) << 1; + bc[3] |= ( *c >> 7 ) & 0x1; + Mc[3] = ( *c >> 5 ) & 0x3; + xmaxc[3] = ( *c++ & 0x1F ) << 1; + xmaxc[3] |= ( *c >> 7 ) & 0x1; + xmc[39] = ( *c >> 4 ) & 0x7; + xmc[40] = ( *c >> 1 ) & 0x7; + xmc[41] = ( *c++ & 0x1 ) << 2; + xmc[41] |= ( *c >> 6 ) & 0x3; + xmc[42] = ( *c >> 3 ) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = ( *c >> 5 ) & 0x7; + xmc[45] = ( *c >> 2 ) & 0x7; + xmc[46] = ( *c++ & 0x3 ) << 1; + xmc[46] |= ( *c >> 7 ) & 0x1; + xmc[47] = ( *c >> 4 ) & 0x7; + xmc[48] = ( *c >> 1 ) & 0x7; + xmc[49] = ( *c++ & 0x1 ) << 2; + xmc[49] |= ( *c >> 6 ) & 0x3; + xmc[50] = ( *c >> 3 ) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + + gsm_dec_Decoder( s, LARc, Nc, bc, Mc, xmaxc, xmc, target ); + + return 0; +} + +void _Pragma( "entrypoint" ) gsm_dec_main( void ) +{ + gsm r; + unsigned i; + gsm_dec_result = 0; + + r = gsm_dec_state_ptr; + + _Pragma( "loopbound min 1 max 1" ) + for ( i = 0; i < SAMPLES; i++ ) { + if ( gsm_dec_decode( r, gsm_dec_gsmdata + i * sizeof( gsm_frame ), + gsm_dec_pcmdata + i * 160 ) ) { + gsm_dec_result = 1; + return; + } + } +} + +int main( int argc, char **argv) +{ + SET_UP + for (jobsComplete=-1; jobsComplete> is a signed arithmetic shift right */ +#define SASR(x, by) ((x) >> (by)) + +/* Table 4.3b Quantization levels of the LTP gain quantizer +*/ +/* bc 0 1 2 3 */ +word gsm_dec_QLB[4] = { 3277, 11469, 21299, 32767 }; + +#endif /* GSM_DEC_PRIVATE_H */ diff --git a/baseline/source/gsm_enc/COPYRIGHT b/baseline/source/gsm_enc/COPYRIGHT new file mode 100644 index 0000000..eba0e52 --- /dev/null +++ b/baseline/source/gsm_enc/COPYRIGHT @@ -0,0 +1,16 @@ +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +Any use of this software is permitted provided that this notice is not +removed and that neither the authors nor the Technische Universitaet Berlin +are deemed to have made any representations as to the suitability of this +software for any purpose nor are held responsible for any defects of +this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + +As a matter of courtesy, the authors request to be informed about uses +this software has found, about bugs in this software, and about any +improvements that may be of general interest. + +Berlin, 28.11.1994 +Jutta Degener +Carsten Bormann diff --git a/baseline/source/gsm_enc/ChangeLog.txt b/baseline/source/gsm_enc/ChangeLog.txt new file mode 100644 index 0000000..4dbeeda --- /dev/null +++ b/baseline/source/gsm_enc/ChangeLog.txt @@ -0,0 +1,8 @@ +2017-06-28: +- Rename benchmark to gsm_enc. +- Add prefix 'gsm_enc_'. +- Introduce gsm_enc_init and gsm_enc_return functions. +- Rewrite negative shifts to avoid undefined behavior. +- Fix comparisons between signed and unsigned types. +- Remove unused variables and parameters. +- Fix memory corruption in gsm_enc_Short_term_analysis_filtering. diff --git a/baseline/source/gsm_enc/data.h b/baseline/source/gsm_enc/data.h new file mode 100644 index 0000000..e656335 --- /dev/null +++ b/baseline/source/gsm_enc/data.h @@ -0,0 +1,452 @@ +#ifndef DATA_H +#define DATA_H + +gsm_signal gsm_enc_pcmdata[] = { + (short)0x0000, (short)0x0000, (short)0x0010, (short)0x0010, (short)0x0010, (short)0x0020, (short)0x0020, (short)0x0018, + (short)0x0028, (short)0x0020, (short)0x0020, (short)0x0028, (short)0x0028, (short)0x0020, (short)0x0030, (short)0x0030, + (short)0x0028, (short)0x0010, (short)0x0008, (short)0x0000, (short)0x0050, (short)0x0060, (short)0x0058, (short)0x00D0, + (short)0x00E0, (short)0x00D0, (short)0x0118, (short)0x0128, (short)0x0118, (short)0x0128, (short)0x0110, (short)0x0100, + (short)0x00A0, (short)0x0058, (short)0x0048, (short)0x0058, (short)0x0060, (short)0x0058, (short)0x0050, (short)0x0048, + (short)0x0040, (short)0x0030, (short)0x0020, (short)0x0010, (short)0x0008, (short)0xFFF8, (short)0xFFE8, (short)0xFFE0, + (short)0xFFD8, (short)0xFFC8, (short)0xFFC0, (short)0xFFC0, (short)0xFF98, (short)0xFF78, (short)0xFF78, (short)0xFFC8, + (short)0x0000, (short)0x0010, (short)0x0040, (short)0x0060, (short)0x0068, (short)0x0078, (short)0x0078, (short)0x0070, + (short)0x00A8, (short)0x00C8, (short)0x00C8, (short)0x00E0, (short)0x00F0, (short)0x00E8, (short)0x00F8, (short)0x00F8, + (short)0x00F0, (short)0x00E0, (short)0x00C8, (short)0x00B8, (short)0x00E8, (short)0x0100, (short)0x00F8, (short)0x00E8, + (short)0x00D8, (short)0x00C0, (short)0x00A8, (short)0x0020, (short)0xFFC0, (short)0xFFA0, (short)0xFFA0, (short)0xFFA8, + (short)0xFFB0, (short)0xFFD0, (short)0xFFF8, (short)0x0000, (short)0x0020, (short)0x0030, (short)0x0030, (short)0x0030, + (short)0x0028, (short)0x0020, (short)0xFFF0, (short)0xFFD0, (short)0xFFC8, (short)0xFFC8, (short)0xFFD0, (short)0xFFD8, + (short)0xFFE8, (short)0xFFF8, (short)0xFFF8, (short)0x0008, (short)0x0018, (short)0x0018, (short)0x0078, (short)0x00B8, + (short)0x00C0, (short)0x0100, (short)0x0130, (short)0x0128, (short)0x0108, (short)0x00D8, (short)0x00C0, (short)0x0078, + (short)0x0038, (short)0x0020, (short)0x0020, (short)0x0000, (short)0xFFE0, (short)0xFFE0, (short)0xFFD8, (short)0xFFC8, + (short)0xFFC8, (short)0xFFA0, (short)0xFF88, (short)0xFF98, (short)0xFF80, (short)0xFF70, (short)0xFF80, (short)0xFF78, + (short)0xFF78, (short)0xFF90, (short)0xFF80, (short)0xFF78, (short)0xFF78, (short)0xFF50, (short)0xFF30, (short)0xFF50, + (short)0xFF38, (short)0xFF30, (short)0xFF40, (short)0xFF58, (short)0xFF70, (short)0xFF80, (short)0xFF50, (short)0xFF38, + (short)0xFF40, (short)0xFF18, (short)0xFF00, (short)0xFF08, (short)0xFF40, (short)0xFF68, (short)0xFF80, (short)0xFF88, + (short)0xFF88, (short)0xFF88, (short)0xFF88, (short)0xFFB8, (short)0xFFE0, (short)0xFFF0, (short)0xFFD0, (short)0xFFB8, + (short)0xFFB8, (short)0xFF90, (short)0xFF70, (short)0xFF70, (short)0xFF50, (short)0xFF40, (short)0xFF40, (short)0xFF58, + (short)0xFF70, (short)0xFF80, (short)0xFFC8, (short)0x0000, (short)0x0018, (short)0x0030, (short)0x0048, (short)0x0048, + (short)0x0028, (short)0x0008, (short)0xFFF8, (short)0xFFD8, (short)0xFFC8, (short)0xFFB8, (short)0xFF98, (short)0xFF78, + (short)0xFF70, (short)0xFFF0, (short)0x0058, (short)0x0088, (short)0x00B8, (short)0x00D0, (short)0x00D8, (short)0x00E8, + (short)0x0138, (short)0x0160, (short)0x0158, (short)0x0170, (short)0x0178, (short)0x0160, (short)0x0168, (short)0x0160, + (short)0x0140, (short)0x0118, (short)0x00F0, (short)0x00C8, (short)0x0098, (short)0x0078, (short)0x0060, (short)0x0018, + (short)0xFFC0, (short)0xFF90, (short)0xFF48, (short)0xFF00, (short)0xFEE8, (short)0xFEC8, (short)0xFEB8, (short)0xFEB8, + (short)0xFEA0, (short)0xFE88, (short)0xFE80, (short)0xFEB8, (short)0xFEF8, (short)0xFF38, (short)0xFFA0, (short)0xFFE8, + (short)0x0008, (short)0x0030, (short)0x0058, (short)0x0068, (short)0x0068, (short)0x0070, (short)0x0068, (short)0x0050, + (short)0x0040, (short)0x0040, (short)0x0020, (short)0x0000, (short)0xFFE8, (short)0xFFF0, (short)0xFFF8, (short)0xFFF8, + (short)0x0038, (short)0x0068, (short)0x0078, (short)0x0038, (short)0x0008, (short)0xFFF0, (short)0xFFE0, (short)0xFFD8, + (short)0xFFD8, (short)0xFFE0, (short)0xFFD0, (short)0xFFC8, (short)0x0000, (short)0x0030, (short)0x0048, (short)0x0068, + (short)0x0080, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0088, (short)0x0078, + (short)0x0098, (short)0x00B0, (short)0x00B8, (short)0x0098, (short)0x0070, (short)0x0058, (short)0x0060, (short)0x0078, + (short)0x00A8, (short)0x00B8, (short)0x00A8, (short)0x00A0, (short)0x0080, (short)0x0068, (short)0x0060, (short)0x0058, + (short)0x0048, (short)0x0030, (short)0x0038, (short)0x0038, (short)0x0030, (short)0x0050, (short)0x0058, (short)0x0060, + (short)0x0030, (short)0x0008, (short)0xFFF8, (short)0xFF90, (short)0xFF48, (short)0xFF28, (short)0xFF10, (short)0xFEF8, + (short)0xFEF0, (short)0xFED8, (short)0xFEB0, (short)0xFEB0, (short)0xFEA8, (short)0xFEB8, (short)0xFED8, (short)0xFEF8, + (short)0xFF10, (short)0xFF20, (short)0xFF40, (short)0xFF58, (short)0xFF80, (short)0xFFA0, (short)0xFFB8, (short)0xFFC8, + (short)0xFFD8, (short)0xFFE0, (short)0xFFF0, (short)0x0048, (short)0x0098, (short)0x00B0, (short)0x0068, (short)0x0018, + (short)0xFFF8, (short)0xFFE8, (short)0xFFF0, (short)0xFFF8, (short)0x0020, (short)0x0038, (short)0x0038, (short)0x0050, + (short)0x0068, (short)0x0070, (short)0x0068, (short)0x0060, (short)0x0060, (short)0x0038, (short)0x0020, (short)0x0018, + (short)0x0040, (short)0x0060, (short)0x0068, (short)0x0040, (short)0x0010, (short)0x0000, (short)0xFFB0, (short)0xFF78, + (short)0xFF70, (short)0xFF90, (short)0xFFA8, (short)0xFFC8, (short)0xFF98, (short)0xFF50, (short)0xFF50, (short)0xFF50, + (short)0xFF58, (short)0xFF68, (short)0xFF48, (short)0xFF20, (short)0xFF18, (short)0xFF38, (short)0xFF60, (short)0xFF70, + (short)0xFF80, (short)0xFF98, (short)0xFFA0, (short)0xFFB8, (short)0xFFD0, (short)0xFFE0, (short)0x0018, (short)0x0048, + (short)0x0058, (short)0x00B0, (short)0x00F8, (short)0x0108, (short)0x0118, (short)0x0120, (short)0x0118, (short)0x0130, + (short)0x0148, (short)0x0140, (short)0x0130, (short)0x0120, (short)0x0108, (short)0x0098, (short)0x0038, (short)0x0018, + (short)0xFFD0, (short)0xFF90, (short)0xFF80, (short)0xFF58, (short)0xFF38, (short)0xFF30, (short)0xFF48, (short)0xFF68, + (short)0xFF78, (short)0xFF88, (short)0xFFB8, (short)0xFFD8, (short)0xFFE8, (short)0xFFD8, (short)0xFFF0, (short)0x0010, + (short)0x0020, (short)0x0020, (short)0x0018, (short)0x0028, (short)0x0030, (short)0x0030, (short)0x0038, (short)0x0060, + (short)0x0080, (short)0x0080, (short)0x00B0, (short)0x00D8, (short)0x00D0, (short)0x00B8, (short)0x00A8, (short)0x00A8, + (short)0x00A0, (short)0x0090, (short)0x0078, (short)0x0070, (short)0x0068, (short)0x0048, (short)0x0018, (short)0x0008, + (short)0x0008, (short)0x0000, (short)0x0000, (short)0xFFE8, (short)0xFFB0, (short)0xFF90, (short)0xFF88, (short)0xFF70, + (short)0xFF60, (short)0xFF60, (short)0xFF90, (short)0xFFC0, (short)0xFFD0, (short)0xFFD8, (short)0xFFE0, (short)0xFFE8, + (short)0x0018, (short)0x0050, (short)0x0058, (short)0x0030, (short)0x0008, (short)0x0000, (short)0x0018, (short)0x0038, + (short)0x0038, (short)0x0048, (short)0x0050, (short)0x0050, (short)0x0020, (short)0x0000, (short)0xFFF8, (short)0xFFB0, + (short)0xFF70, (short)0xFF68, (short)0xFFB0, (short)0xFFE8, (short)0xFFF8, (short)0xFFF8, (short)0xFFF8, (short)0xFFF0, + (short)0x0030, (short)0x0070, (short)0x0090, (short)0x0098, (short)0x0098, (short)0x0090, (short)0x00A0, (short)0x00B0, + (short)0x00B8, (short)0x00C0, (short)0x00C0, (short)0x00A8, (short)0x0098, (short)0x0088, (short)0x0078, (short)0x0050, + (short)0x0030, (short)0x0020, (short)0xFFD8, (short)0xFF98, (short)0xFF88, (short)0xFF50, (short)0xFF20, (short)0xFF18, + (short)0xFEF8, (short)0xFEE0, (short)0xFEE8, (short)0xFE70, (short)0xFE08, (short)0xFE00, (short)0xFE48, (short)0xFE98, + (short)0xFEB8, (short)0xFEE8, (short)0xFF10, (short)0xFF28, (short)0xFF18, (short)0xFF10, (short)0xFF18, (short)0xFF48, + (short)0xFF70, (short)0xFF88, (short)0xFFE0, (short)0x0028, (short)0x0040, (short)0x0058, (short)0x0068, (short)0x0070, + (short)0x0078, (short)0x0070, (short)0x0068, (short)0x0068, (short)0x0078, (short)0x0080, (short)0x0080, (short)0x0088, + (short)0x0088, (short)0x0080, (short)0x0058, (short)0x0030, (short)0x0020, (short)0x0018, (short)0x0018, (short)0x0018, + (short)0x0050, (short)0x0090, (short)0x00A0, (short)0x0080, (short)0x0060, (short)0x0050, (short)0x0030, (short)0x0018, + (short)0x0010, (short)0x0028, (short)0x0038, (short)0x0038, (short)0x0018, (short)0xFFF8, (short)0xFFF0, (short)0x0000, + (short)0x0020, (short)0x0020, (short)0x0030, (short)0x0030, (short)0x0030, (short)0x0040, (short)0x0050, (short)0x0050, + (short)0x0050, (short)0x0048, (short)0x0048, (short)0x0048, (short)0x0048, (short)0x0048, (short)0x0078, (short)0x00A0, + (short)0x00A8, (short)0x00C0, (short)0x00C8, (short)0x00C0, (short)0x00D0, (short)0x00E0, (short)0x00D8, (short)0x00E8, + (short)0x00F0, (short)0x00E0, (short)0x0100, (short)0x0118, (short)0x0110, (short)0x0100, (short)0x00F0, (short)0x00D8, + (short)0x0090, (short)0x0048, (short)0x0028, (short)0x0020, (short)0x0020, (short)0x0020, (short)0x0038, (short)0x0050, + (short)0x0050, (short)0x0050, (short)0x0048, (short)0x0040, (short)0x0050, (short)0x0060, (short)0x0060, (short)0x0040, + (short)0xFFC0, (short)0xFF58, (short)0xFF40, (short)0xFF90, (short)0xFFE8, (short)0x0000, (short)0x0020, (short)0x0030, + (short)0x0030, (short)0x0068, (short)0x0098, (short)0x00A8, (short)0x0110, (short)0x0168, (short)0x0170, (short)0x0148, + (short)0x0118, (short)0x00F0, (short)0x00E8, (short)0x00E0, (short)0x00D0, (short)0x0098, (short)0x0060, (short)0x0040, + (short)0x0000, (short)0xFFD8, (short)0xFFD8, (short)0xFFC0, (short)0xFFB0, (short)0xFFB0, (short)0xFF78, (short)0xFF30, + (short)0xFF10, (short)0xFEF0, (short)0xFEE8, (short)0xFEF0, (short)0xFEC8, (short)0xFED0, (short)0xFEF8, (short)0xFF00, + (short)0xFF10, (short)0xFF20, (short)0xFF50, (short)0xFF78, (short)0xFF90, (short)0xFF80, (short)0xFF70, (short)0xFF70, + (short)0xFF80, (short)0xFF98, (short)0xFFA0, (short)0xFFB8, (short)0xFFD0, (short)0xFFD8, (short)0xFFF0, (short)0x0000, + (short)0x0008, (short)0x0028, (short)0x0048, (short)0x0058, (short)0x0078, (short)0x0070, (short)0x0058, (short)0x0068, + (short)0x0098, (short)0x00B8, (short)0x00D8, (short)0x00F0, (short)0x00F0, (short)0x00E8, (short)0x00F8, (short)0x0100, + (short)0x00D8, (short)0x00D0, (short)0x00C8, (short)0x00E8, (short)0x0100, (short)0x00F0, (short)0x00E0, (short)0x00C8, + (short)0x00B8, (short)0x00A0, (short)0x0078, (short)0x0058, (short)0x0038, (short)0x0020, (short)0x0010, (short)0x0010, + (short)0x0018, (short)0x0010, (short)0x0010, (short)0x0010, (short)0x0018, (short)0x0028, (short)0x0008, (short)0xFFE0, + (short)0xFFC8, (short)0xFF80, (short)0xFF48, (short)0xFF38, (short)0xFF40, (short)0xFF48, (short)0xFF48, (short)0xFF70, + (short)0xFF90, (short)0xFFA8, (short)0xFFB8, (short)0xFFC0, (short)0xFFC8, (short)0xFFC0, (short)0xFFC0, (short)0xFFC0, + (short)0xFFB0, (short)0xFFA0, (short)0xFFA0, (short)0xFFA0, (short)0xFFA8, (short)0xFFB0, (short)0xFF68, (short)0xFF28, + (short)0xFF08, (short)0xFEF8, (short)0xFEF8, (short)0xFEE8, (short)0xFEE0, (short)0xFED8, (short)0xFEA8, (short)0xFE98, + (short)0xFEA8, (short)0xFEA8, (short)0xFEA0, (short)0xFEA0, (short)0xFED0, (short)0xFF00, (short)0xFF30, (short)0xFF28, + (short)0xFF38, (short)0xFF58, (short)0xFF48, (short)0xFF40, (short)0xFF48, (short)0xFFB0, (short)0x0010, (short)0x0038, + (short)0x0028, (short)0x0010, (short)0x0008, (short)0x0050, (short)0x00A0, (short)0x00B8, (short)0x00A0, (short)0x0080, + (short)0x0070, (short)0x0090, (short)0x00B0, (short)0x00B0, (short)0x00B8, (short)0x00B8, (short)0x00B0, (short)0x00C0, + (short)0x00D0, (short)0x00C8, (short)0x00A0, (short)0x0068, (short)0x0038, (short)0xFFF0, (short)0xFFB0, (short)0xFF88, + (short)0xFF78, (short)0xFF68, (short)0xFF60, (short)0xFF90, (short)0xFFC0, (short)0xFFE0, (short)0x0000, (short)0x0020, + (short)0x0030, (short)0x00A0, (short)0x0110, (short)0x0138, (short)0x0140, (short)0x0148, (short)0x0148, (short)0x0110, + (short)0x00E8, (short)0x00C0, (short)0x00A0, (short)0x0088, (short)0x0068, (short)0x0008, (short)0xFFB0, (short)0xFF88, + (short)0xFF58, (short)0xFF30, (short)0xFF20, (short)0xFEF8, (short)0xFED8, (short)0xFED8, (short)0xFF00, (short)0xFF20, + (short)0xFF38, (short)0xFF50, (short)0xFF68, (short)0xFF88, (short)0xFFA0, (short)0xFFB8, (short)0x0020, (short)0x0080, + (short)0x00A0, (short)0x00D8, (short)0x0100, (short)0x0100, (short)0x0138, (short)0x0168, (short)0x0148, (short)0x0128, + (short)0x0120, (short)0x00F8, (short)0x00E8, (short)0x00E0, (short)0x00C0, (short)0x00A8, (short)0x00B0, (short)0x0098, + (short)0x0070, (short)0x0048, (short)0x0030, (short)0xFFD0, (short)0xFF60, (short)0xFF48, (short)0xFF10, (short)0xFEA8, + (short)0xFEA8, (short)0xFEC0, (short)0xFEC0, (short)0xFEE8, (short)0xFEB0, (short)0xFE58, (short)0xFE88, (short)0xFED0, + (short)0xFEB8, (short)0xFE48, (short)0xFE58, (short)0xFEE8, (short)0xFF28, (short)0xFF18, (short)0xFF60, (short)0x00A0, + (short)0x01A0, (short)0x0188, (short)0x0178, (short)0x0208, (short)0x0208, (short)0x0100, (short)0x0018, (short)0xFFE0, + (short)0xFEE0, (short)0xFD68, (short)0xFD00, (short)0xFD60, (short)0xFD70, (short)0xFDA8, (short)0xFF00, (short)0x00A0, + (short)0x0170, (short)0x0210, (short)0x02D8, (short)0x0310, (short)0x0218, (short)0x00A0, (short)0xFFA0, (short)0xFDF0, + (short)0xFBD8, (short)0xFB08, (short)0xF9C0, (short)0xF830, (short)0xF8D8, (short)0xFCC0, (short)0x0038, (short)0x01A0, + (short)0x0380, (short)0x0A18, (short)0x0F50, (short)0x0DB0, (short)0x0C30, (short)0x0E18, (short)0x0CA8, (short)0x0570, + (short)0xFF98, (short)0xFE38, (short)0xFBA0, (short)0xF700, (short)0xF5D0, (short)0xF7C8, (short)0xF9A8, (short)0xFB48, + (short)0xFBB0, (short)0xFC78, (short)0xFF00, (short)0xFE98, (short)0xFB20, (short)0xFA48, (short)0xFAC0, (short)0xF8C8, + (short)0xF6E0, (short)0xF9C0, (short)0xFE08, (short)0xFF80, (short)0x0428, (short)0x0B70, (short)0x0E18, (short)0x0D38, + (short)0x0D38, (short)0x0C28, (short)0x01D0, (short)0xF578, (short)0xF108, (short)0xFB50, (short)0x0498, (short)0x0428, + (short)0x0CE8, (short)0x2190, (short)0x29F0, (short)0x22E0, (short)0x1F68, (short)0x2050, (short)0x1810, (short)0x0710, + (short)0xFA98, (short)0xF438, (short)0xEE68, (short)0xE950, (short)0xEBC8, (short)0xF538, (short)0xFEB8, (short)0x0240, + (short)0x0460, (short)0x09D0, (short)0x0978, (short)0xFFF8, (short)0xF810, (short)0xF190, (short)0xE8D0, (short)0xE290, + (short)0xDF60, (short)0xDFF0, (short)0xE668, (short)0xEC20, (short)0xF138, (short)0xFAC0, (short)0x04F0, (short)0x08D0, + (short)0x08C8, (short)0x0B18, (short)0x09F8, (short)0x0230, (short)0xFA38, (short)0xFA68, (short)0xFC78, (short)0xF9B8, + (short)0xF850, (short)0xFEA8, (short)0x05B8, (short)0x0690, (short)0x02E8, (short)0x0268, (short)0x0498, (short)0xFCB0, + (short)0xF018, (short)0xEDF8, (short)0x0090, (short)0x0F48, (short)0x0C70, (short)0x1278, (short)0x27B8, (short)0x2EA0, + (short)0x21F8, (short)0x1920, (short)0x1918, (short)0x1530, (short)0x0638, (short)0xF858, (short)0xF720, (short)0xF9F8, + (short)0xF600, (short)0xF850, (short)0x0590, (short)0x0EE0, (short)0x1000, (short)0x10D8, (short)0x1460, (short)0x10F8, + (short)0x0500, (short)0xFBC0, (short)0xF7A8, (short)0xF250, (short)0xEC00, (short)0xEB30, (short)0xF1C8, (short)0xF920, + (short)0xFC90, (short)0x0190, (short)0x0A60, (short)0x0E80, (short)0x0DB0, (short)0x0AD8, (short)0x0690, (short)0x0168, + (short)0xFF20, (short)0xFBD0, (short)0xF6F8, (short)0xF660, (short)0xF680, (short)0xF5B0, (short)0xF7C0, (short)0xF120, + (short)0xEA90, (short)0xF030, (short)0xEC18, (short)0xE190, (short)0xE558, (short)0xFF20, (short)0x1090, (short)0x0C50, + (short)0x1248, (short)0x2788, (short)0x2AD0, (short)0x1628, (short)0x08F0, (short)0x0BA8, (short)0x0538, (short)0xEF48, + (short)0xE410, (short)0xEB10, (short)0xEF68, (short)0xEA28, (short)0xEC40, (short)0xFC18, (short)0x08A8, (short)0x0818, + (short)0x0778, (short)0x0858, (short)0x02F8, (short)0xF8E8, (short)0xF1F0, (short)0xEF40, (short)0xECD0, (short)0xE958, + (short)0xEA70, (short)0xF260, (short)0xFAF0, (short)0xFFA0, (short)0x04A0, (short)0x0CF8, (short)0x10F8, (short)0x0EA0, + (short)0x0D48, (short)0x0BE8, (short)0x05E0, (short)0x03B0, (short)0x0358, (short)0xFF18, (short)0xFB40, (short)0xF9B0, + (short)0xF9C0, (short)0xF7C0, (short)0xEE90, (short)0xEAA0, (short)0xEE00, (short)0xE888, (short)0xE200, (short)0xEF00, + (short)0x0948, (short)0x1400, (short)0x1270, (short)0x1D88, (short)0x2CD8, (short)0x2488, (short)0x0DA8, (short)0x04B8, + (short)0x0548, (short)0xF7B0, (short)0xE3F0, (short)0xE268, (short)0xEFF8, (short)0xF5A0, (short)0xF320, (short)0xFC68, + (short)0x0BF0, (short)0x0FA0, (short)0x0A50, (short)0x01F8, (short)0xFE60, (short)0xFC48, (short)0xF340, (short)0xEB28, + (short)0xED58, (short)0xF3C0, (short)0xF5B8, (short)0xF738, (short)0x00F8, (short)0x0C70, (short)0x0E90, (short)0x0DE8, + (short)0x1190, (short)0x12B0, (short)0x1058, (short)0x0B98, (short)0x0638, (short)0x0868, (short)0x0998, (short)0x02B0, + (short)0xFE50, (short)0x0120, (short)0x02A0, (short)0xFC90, (short)0xF810, (short)0xF9D0, (short)0xF818, (short)0xF290, + (short)0xF240, (short)0xF6D0, (short)0x0A48, (short)0x1AD8, (short)0x1840, (short)0x1C18, (short)0x2B18, (short)0x29F0, + (short)0x1608, (short)0x08B8, (short)0x0778, (short)0x0128, (short)0xF118, (short)0xE868, (short)0xEDA0, (short)0xF310, + (short)0xF248, (short)0xF558, (short)0x0058, (short)0x0970, (short)0x0688, (short)0x0108, (short)0xFD08, (short)0xF988, + (short)0xF558, (short)0xF0A0, (short)0xF0B0, (short)0xF540, (short)0xF6E8, (short)0xFCA0, (short)0x0758, (short)0x0CD0, + (short)0x0F60, (short)0x1338, (short)0x1458, (short)0x1278, (short)0x0FD0, (short)0x0CA8, (short)0x0D50, (short)0x0D10, + (short)0x0798, (short)0x0398, (short)0x0428, (short)0x04F0, (short)0x0278, (short)0xFF98, (short)0x0178, (short)0x0088, + (short)0xFB08, (short)0xF660, (short)0xF1A8, (short)0xEF18, (short)0xF9E8, (short)0x0C00, (short)0x11C8, (short)0x1260, + (short)0x1B60, (short)0x21B0, (short)0x18E0, (short)0x0B08, (short)0x04C8, (short)0x0078, (short)0xF730, (short)0xEF60, + (short)0xEB18, (short)0xEC10, (short)0xF290, (short)0xF800, (short)0xFB60, (short)0xFF60, (short)0x0080, (short)0xFFA8, + (short)0xFB08, (short)0xF1A8, (short)0xED10, (short)0xEFF0, (short)0xEED0, (short)0xEB10, (short)0xEFE8, (short)0xF8F0, + (short)0xFDE0, (short)0x0298, (short)0x0528, (short)0x0598, (short)0x0928, (short)0x0A30, (short)0x0670, (short)0x08E8, + (short)0x0BC0, (short)0x0698, (short)0x0210, (short)0x0390, (short)0x0560, (short)0x0288, (short)0xF910, (short)0xF468, + (short)0xF560, (short)0xF3E0, (short)0xEE10, (short)0xE8B0, (short)0xE508, (short)0xEED0, (short)0x03E0, (short)0x0638, + (short)0xFFA8, (short)0x0BB8, (short)0x2078, (short)0x1FA8, (short)0x0EF0, (short)0x0648, (short)0x05C8, (short)0xFF18, + (short)0xF588, (short)0xEE20, (short)0xED88, (short)0xF5A0, (short)0xFBA8, (short)0xFBC0, (short)0xFA98, (short)0xFA20, + (short)0xF7D8, (short)0xF2D0, (short)0xEF48, (short)0xE998, (short)0xE378, (short)0xE530, (short)0xE868, (short)0xE890, + (short)0xEDD0, (short)0xF798, (short)0xFBC0, (short)0xFD20, (short)0x0178, (short)0x0490, (short)0x04A0, (short)0x0758, + (short)0x0858, (short)0x0490, (short)0x04F8, (short)0x0858, (short)0x06F0, (short)0x05F8, (short)0x0450, (short)0x0098, + (short)0xFE60, (short)0xFDA0, (short)0xF9E0, (short)0xF358, (short)0xEDC0, (short)0xF308, (short)0xFFE0, (short)0x0018, + (short)0xFB80, (short)0x0948, (short)0x1DB8, (short)0x1D08, (short)0x0F88, (short)0x0B48, (short)0x0C50, (short)0x09C0, + (short)0xFF78, (short)0xF1A0, (short)0xEF28, (short)0xF6B8, (short)0xF9F0, (short)0xF6F0, (short)0xF688, (short)0xF9E0, + (short)0xF9C0, (short)0xF4C8, (short)0xEBD8, (short)0xE7E8, (short)0xEBE0, (short)0xE8C8, (short)0xE100, (short)0xE518, + (short)0xF0B8, (short)0xF728, (short)0xF770, (short)0xF878, (short)0xFF58, (short)0x06B0, (short)0x0430, (short)0x0060, + (short)0x0390, (short)0x0A18, (short)0x0B98, (short)0x06C8, (short)0x0710, (short)0x0CF0, (short)0x08D0, (short)0x01F8, + (short)0x0280, (short)0x0238, (short)0xFD78, (short)0xF868, (short)0xF198, (short)0xF670, (short)0x0930, (short)0x0A78, + (short)0xFB38, (short)0x04F0, (short)0x1EB8, (short)0x1E98, (short)0x0F68, (short)0x0EC8, (short)0x1548, (short)0x1480, + (short)0x0C60, (short)0x00B0, (short)0xFEF8, (short)0x0830, (short)0x0838, (short)0x0160, (short)0x0380, (short)0x07E8, + (short)0x0270, (short)0xFBA0, (short)0xF9C0, (short)0xF450, (short)0xEE08, (short)0xED08, (short)0xEE10, (short)0xEF20, + (short)0xF1C0, (short)0xF800, (short)0xFE70, (short)0x00B0, (short)0x02D8, (short)0x07C8, (short)0x09F0, (short)0x09A8, + (short)0x0A60, (short)0x0B28, (short)0x0C80, (short)0x0D58, (short)0x0BD0, (short)0x0A48, (short)0x0900, (short)0x0768, + (short)0x03D0, (short)0x00E0, (short)0xFFF8, (short)0xFBD8, (short)0xF5E8, (short)0xFE18, (short)0x0FE8, (short)0x1060, + (short)0x05C8, (short)0x1078, (short)0x2638, (short)0x2580, (short)0x1740, (short)0x14E8, (short)0x19D0, (short)0x17D8, + (short)0x0E10, (short)0x0270, (short)0x0120, (short)0x0900, (short)0x0870, (short)0x0290, (short)0x03A0, (short)0x0600, + (short)0x0100, (short)0xFE28, (short)0xFF28, (short)0xF838, (short)0xF0B8, (short)0xF238, (short)0xF530, (short)0xF440, + (short)0xF440, (short)0xFA38, (short)0x0198, (short)0x03A8, (short)0x03D0, (short)0x0780, (short)0x0AB8, (short)0x0B58, + (short)0x0B10, (short)0x0AD8, (short)0x0A08, (short)0x0878, (short)0x07C8, (short)0x0648, (short)0x01A0, (short)0xFF48, + (short)0xFE58, (short)0xFA68, (short)0xF7D0, (short)0xF758, (short)0xF470, (short)0xF5B0, (short)0x02A8, (short)0x0A58, + (short)0x0448, (short)0x07C8, (short)0x1708, (short)0x1970, (short)0x0EC8, (short)0x0A40, (short)0x0CD0, (short)0x0D28, + (short)0x0838, (short)0x0010, (short)0xFAE0, (short)0xFCB0, (short)0xFEB8, (short)0xFCE8, (short)0xFBA8, (short)0xFD10, + (short)0xFBC8, (short)0xF910, (short)0xF960, (short)0xF830, (short)0xF4D8, (short)0xF500, (short)0xF860, (short)0xF9F0, + (short)0xFB58, (short)0xFE48, (short)0x0050, (short)0x0418, (short)0x0910, (short)0x0940, (short)0x0830, (short)0x0AC8, + (short)0x0C88, (short)0x0A50, (short)0x07C0, (short)0x0700, (short)0x0590, (short)0x0268, (short)0xFFF0, (short)0xFBA8, + (short)0xF720, (short)0xF698, (short)0xF2E0, (short)0xEB68, (short)0xEDA0, (short)0xFC00, (short)0x0358, (short)0xFF30, + (short)0x0398, (short)0x1220, (short)0x1860, (short)0x1368, (short)0x10C0, (short)0x12F0, (short)0x12A0, (short)0x0E08, + (short)0x0780, (short)0x0010, (short)0xFAD8, (short)0xF990, (short)0xF7E0, (short)0xF278, (short)0xEE10, (short)0xEB98, + (short)0xE7A0, (short)0xE6F8, (short)0xEA30, (short)0xE980, (short)0xE420, (short)0xE440, (short)0xEBA8, (short)0xEF98, + (short)0xEF68, (short)0xF288, (short)0xF7A8, (short)0xFC90, (short)0x01F8, (short)0x0528, (short)0x0630, (short)0x08E8, + (short)0x0C98, (short)0x0D50, (short)0x0B98, (short)0x0920, (short)0x0678, (short)0x03F0, (short)0x0260, (short)0xFE00, + (short)0xF810, (short)0xF4B8, (short)0xF0C0, (short)0xEB68, (short)0xEF58, (short)0xFAE8, (short)0xFDE0, (short)0xF680, + (short)0xF910, (short)0x06E0, (short)0x0C20, (short)0x05D8, (short)0x0408, (short)0x05C8, (short)0x0450, (short)0x02D0, + (short)0x0128, (short)0xFB78, (short)0xF668, (short)0xF430, (short)0xF150, (short)0xED90, (short)0xE870, (short)0xE448, + (short)0xE2E0, (short)0xE048, (short)0xDDD0, (short)0xDF08, (short)0xE0E0, (short)0xE098, (short)0xE258, (short)0xE520, + (short)0xE6A8, (short)0xEA28, (short)0xEF88, (short)0xF2A8, (short)0xF548, (short)0xFBA8, (short)0x01C8, (short)0x03F8, + (short)0x0748, (short)0x0C88, (short)0x0E98, (short)0x0DB8, (short)0x0D98, (short)0x0D50, (short)0x0B68, (short)0x0970, + (short)0x06C0, (short)0x0238, (short)0xFE18, (short)0xFB08, (short)0xF820, (short)0xF780, (short)0xF970, (short)0xF9B0, + (short)0xF880, (short)0xFA28, (short)0x0028, (short)0x0698, (short)0x0948, (short)0x08D0, (short)0x09E0, (short)0x0DD0, + (short)0x1010, (short)0x0D40, (short)0x0958, (short)0x0728, (short)0x0308, (short)0xFDA0, (short)0xF9F8, (short)0xF418, + (short)0xEC98, (short)0xE8B8, (short)0xE618, (short)0xE200, (short)0xDED0, (short)0xDF48, (short)0xE100, (short)0xE180, + (short)0xE160, (short)0xE3C8, (short)0xE898, (short)0xEDD8, (short)0xF250, (short)0xF558, (short)0xFB00, (short)0x02F8, + (short)0x07B0, (short)0x0B80, (short)0x1108, (short)0x1518, (short)0x1660, (short)0x1770, (short)0x1870, (short)0x16F8, + (short)0x1300, (short)0x0F78, (short)0x0FC0, (short)0x1070, (short)0x0CE8, (short)0x0AF8, (short)0x0BD8, (short)0x0D28, + (short)0x10A8, (short)0x1370, (short)0x10A0, (short)0x1040, (short)0x1518, (short)0x1740, (short)0x1550, (short)0x1398, + (short)0x10E0, (short)0x0AC8, (short)0x0640, (short)0x0348, (short)0xFD18, (short)0xF658, (short)0xF1D8, (short)0xEC20, + (short)0xE760, (short)0xE550, (short)0xE4B8, (short)0xE418, (short)0xE438, (short)0xE508, (short)0xE738, (short)0xEB18, + (short)0xF0C8, (short)0xF618, (short)0xF988, (short)0xFEC8, (short)0x0518, (short)0x09D8, (short)0x1118, (short)0x17F0, + (short)0x1BB0, (short)0x1E28, (short)0x2120, (short)0x23D8, (short)0x2638, (short)0x2418, (short)0x2080, (short)0x1D30, + (short)0x1CE8, (short)0x1D98, (short)0x1CA8, (short)0x1AD8, (short)0x1960, (short)0x17F8, (short)0x1A40, (short)0x1CF8, + (short)0x1D38, (short)0x1C30, (short)0x1A68, (short)0x1860, (short)0x1480, (short)0x1020, (short)0x0B68, (short)0x03E8, + (short)0xFBA8, (short)0xF508, (short)0xEE40, (short)0xE820, (short)0xE338, (short)0xDE88, (short)0xDA30, (short)0xD7D0, + (short)0xD728, (short)0xD7D8, (short)0xD998, (short)0xDC10, (short)0xDFB0, (short)0xE470, (short)0xE948, (short)0xEF98, + (short)0xF5F0, (short)0xFC38, (short)0x0228, (short)0x0798, (short)0x0D98, (short)0x1320, (short)0x1760, (short)0x1A70, + (short)0x1BE0, (short)0x1CC0, (short)0x1D98, (short)0x1A88, (short)0x1658, (short)0x12A0, (short)0x1180, (short)0x10A8, + (short)0x0ED0, (short)0x0CC8, (short)0x0AD8, (short)0x0920, (short)0x0B70, (short)0x0E30, (short)0x0EE8, (short)0x0D80, + (short)0x0BE0, (short)0x0AC0, (short)0x09B8, (short)0x0890, (short)0x0690, (short)0x01F8, (short)0xFD30, (short)0xF9F0, + (short)0xF5B0, (short)0xF188, (short)0xEE38, (short)0xE9E8, (short)0xE5E8, (short)0xE3E0, (short)0xE4A0, (short)0xE608, + (short)0xE738, (short)0xE858, (short)0xE980, (short)0xEC20, (short)0xF030, (short)0xF450, (short)0xF878, (short)0xFC68, + (short)0xFF68, (short)0x03C8, (short)0x08B8, (short)0x0D00, (short)0x1038, (short)0x12D8, (short)0x1490, (short)0x1648, + (short)0x16B8, (short)0x1468, (short)0x1160, (short)0x0FA8, (short)0x1038, (short)0x1058, (short)0x0F88, (short)0x0E50, + (short)0x0CC8, (short)0x0CC0, (short)0x0FC0, (short)0x1220, (short)0x12A0, (short)0x10F8, (short)0x0F20, (short)0x0D28, + (short)0x0C78, (short)0x0BB8, (short)0x08D0, (short)0x01C8, (short)0xFB38, (short)0xF660, (short)0xF330, (short)0xF078, + (short)0xEC28, (short)0xE6C8, (short)0xE2C0, (short)0xE050, (short)0xDFC8, (short)0xE038, (short)0xE160, (short)0xE300, + (short)0xE568, (short)0xE6B8, (short)0xE9A0, (short)0xED50, (short)0xF238, (short)0xF6D8, (short)0xFB08, (short)0xFF10, + (short)0x02E8, (short)0x06A0, (short)0x0AC0, (short)0x0DC8, (short)0x1010, (short)0x1168, (short)0x1018, (short)0x0E90, + (short)0x0BF8, (short)0x0B08, (short)0x0A50, (short)0x09F0, (short)0x0960, (short)0x0888, (short)0x0808, (short)0x09C8, + (short)0x0BA8, (short)0x0EE8, (short)0x1070, (short)0x10D0, (short)0x0F58, (short)0x0D60, (short)0x0BA0, (short)0x0A60, + (short)0x08F0, (short)0x0608, (short)0xFFB0, (short)0xF938, (short)0xF360, (short)0xF030, (short)0xEE20, (short)0xEB70, + (short)0xE7A8, (short)0xE410, (short)0xE140, (short)0xDFC8, (short)0xDFF8, (short)0xE1F0, (short)0xE448, (short)0xE6D0, + (short)0xE780, (short)0xE9E8, (short)0xECF0, (short)0xF248, (short)0xF730, (short)0xFBC0, (short)0xFF80, (short)0x0310, + (short)0x0670, (short)0x0A98, (short)0x0D88, (short)0x0FD8, (short)0x10C0, (short)0x0EB0, (short)0x0C48, (short)0x08B8, + (short)0x0998, (short)0x0AC0, (short)0x0C68, (short)0x0B78, (short)0x09C8, (short)0x0838, (short)0x08F8, (short)0x0A80, + (short)0x0CA0, (short)0x0E10, (short)0x0E48, (short)0x0D58, (short)0x0A28, (short)0x0750, (short)0x04F0, (short)0x0228, + (short)0xFEE8, (short)0xFA80, (short)0xF468, (short)0xEED0, (short)0xEAE0, (short)0xE8B8, (short)0xE718, (short)0xE5B0, + (short)0xE4A8, (short)0xE410, (short)0xE480, (short)0xE548, (short)0xE738, (short)0xE9B0, (short)0xED80, (short)0xF0B8, + (short)0xF480, (short)0xF7B0, (short)0xFB70, (short)0xFED0, (short)0x0328, (short)0x0720, (short)0x0A98, (short)0x0E00, + (short)0x10F8, (short)0x12E0, (short)0x12A8, (short)0x11B0, (short)0x0F58, (short)0x0F38, (short)0x0E88, (short)0x0F08, + (short)0x0FC0, (short)0x0FF0, (short)0x10B8, (short)0x1138, (short)0x1198, (short)0x13D0, (short)0x1638, (short)0x17E8, + (short)0x1758, (short)0x1628, (short)0x1460, (short)0x10E8, (short)0x0CA0, (short)0x0848, (short)0x0280, (short)0xFC90, + (short)0xF700, (short)0xF0F8, (short)0xEB18, (short)0xE638, (short)0xE1B8, (short)0xDE78, (short)0xDC58, (short)0xDBB8, + (short)0xDC28, (short)0xDDB0, (short)0xE030, (short)0xE330, (short)0xE6F0, (short)0xEC20, (short)0xF210, (short)0xF7C0, + (short)0xFCE0, (short)0x0150, (short)0x0570, (short)0x08F0, (short)0x0C70, (short)0x0F50, (short)0x12B8, (short)0x1560, + (short)0x16E0, (short)0x1630, (short)0x14E8, (short)0x1298, (short)0x11B8, (short)0x1170, (short)0x11B8, (short)0x11C0, + (short)0x0FE8, (short)0x0E58, (short)0x0CB8, (short)0x0C50, (short)0x0D68, (short)0x0E98, (short)0x0E30, (short)0x0C28, + (short)0x0A10, (short)0x06D8, (short)0x02E0, (short)0xFEA0, (short)0xFA18, (short)0xF4E8, (short)0xF018, (short)0xEB68, + (short)0xE6E8, (short)0xE310, (short)0xDFC8, (short)0xDD38, (short)0xDBF8, (short)0xDC38, (short)0xDDD0, (short)0xE070, + (short)0xE390, (short)0xE760, (short)0xEB88, (short)0xEF20, (short)0xF378, (short)0xF830, (short)0xFCE0, (short)0x00F8, + (short)0x0480, (short)0x0768, (short)0x0968, (short)0x0AE0, (short)0x0BB8, (short)0x0C10, (short)0x0BB0, (short)0x0A78, + (short)0x08E0, (short)0x06E8, (short)0x0540, (short)0x0870, (short)0x0BE0, (short)0x0ED0, (short)0x0E40, (short)0x0D10, + (short)0x0CC8, (short)0x0E28, (short)0x0FA0, (short)0x0FB0, (short)0x0F18, (short)0x0DD0, (short)0x0BC8, (short)0x08E8, + (short)0x0628, (short)0x0300, (short)0xFF18, (short)0xFB40, (short)0xF780, (short)0xF388, (short)0xF028, (short)0xED80, + (short)0xEB18, (short)0xE968, (short)0xE8C0, (short)0xE738, (short)0xE658, (short)0xE698, (short)0xE888, (short)0xEB38, + (short)0xEDA0, (short)0xF178, (short)0xF5B8, (short)0xFA28, (short)0xFEA8, (short)0x0300, (short)0x06C8, (short)0x0960, + (short)0x0B70, (short)0x0CE0, (short)0x0D70, (short)0x0D50, (short)0x0C60, (short)0x0890, (short)0x0418, (short)0x0028, + (short)0x01D0, (short)0x03F8, (short)0x05A8, (short)0x0700, (short)0x0808, (short)0x09A0, (short)0x0B18, (short)0x0CC8, + (short)0x0D90, (short)0x0E68, (short)0x0EC0, (short)0x0E30, (short)0x0C28, (short)0x09D8, (short)0x0730, (short)0x0308, + (short)0xFED8, (short)0xFAC0, (short)0xF598, (short)0xF0D8, (short)0xECE0, (short)0xEAA8, (short)0xE948, (short)0xE8D0, + (short)0xE850, (short)0xE888, (short)0xE910, (short)0xEAD0, (short)0xED68, (short)0xF018, (short)0xF350, (short)0xF6B8, + (short)0xFAE0, (short)0xFF00, (short)0x02D8, (short)0x05E8, (short)0x0830, (short)0x09F8, (short)0x0B08, (short)0x0B80, + (short)0x0B60, (short)0x0988, (short)0x0648, (short)0x02D0, (short)0x0150, (short)0x01E8, (short)0x0270, (short)0x03E0, + (short)0x0538, (short)0x0658, (short)0x0918, (short)0x0C00, (short)0x0E88, (short)0x10B8, (short)0x12A0, (short)0x13E0, + (short)0x1488, (short)0x1448, (short)0x1368, (short)0x1120, (short)0x0DD0, (short)0x0A40, (short)0x0608, (short)0x0148, + (short)0xFC80, (short)0xF860, (short)0xF4D8, (short)0xF1C0, (short)0xF008, (short)0xEF38, (short)0xEE78, (short)0xEE98, + (short)0xEF90, (short)0xF170, (short)0xF390, (short)0xF5C0, (short)0xF888, (short)0xFB48, (short)0xFDF0, (short)0x0078, + (short)0x03D0, (short)0x06C8, (short)0x08F8, (short)0x0AA0, (short)0x0BC8, (short)0x0C48, (short)0x0B30, (short)0x0978, + (short)0x06A8, (short)0x0530, (short)0x03F0, (short)0x0438, (short)0x03C0, (short)0x0350, (short)0x0360, (short)0x04E8, + (short)0x0698, (short)0x07D0, (short)0x08D0, (short)0x0998, (short)0x0A70, (short)0x0B48, (short)0x0B70, (short)0x0AD0, + (short)0x09C0, (short)0x0890, (short)0x0730, (short)0x0588, (short)0x0358, (short)0x0140, (short)0xFF58, (short)0xFD40, + (short)0xFB68, (short)0xF9E8, (short)0xF828, (short)0xF6D0, (short)0xF608, (short)0xF5D8, (short)0xF610, (short)0xF668, + (short)0xF778, (short)0xF8E8, (short)0xFA48, (short)0xFCC8, (short)0xFF50, (short)0x01C8, (short)0x0428, (short)0x0640, + (short)0x07D0, (short)0x09D0, (short)0x0B40, (short)0x0BF8, (short)0x0C30, (short)0x0C08, (short)0x0B08, (short)0x0988, + (short)0x07C0, (short)0x0670, (short)0x0608, (short)0x0590, (short)0x0588, (short)0x05B0, (short)0x05E0, (short)0x06B8, + (short)0x0748, (short)0x0758, (short)0x0700, (short)0x06A8, (short)0x0620, (short)0x05D8, (short)0x0590, (short)0x0528, + (short)0x03A8, (short)0x0240, (short)0x0108, (short)0xFF38, (short)0xFD50, (short)0xFBA0, (short)0xFA38, (short)0xF920, + (short)0xF860, (short)0xF6E8, (short)0xF640, (short)0xF628, (short)0xF680, (short)0xF720, (short)0xF800, (short)0xF8E0, + (short)0xF9A0, (short)0xFA78, (short)0xFB88, (short)0xFD20, (short)0xFEA0, (short)0x0008, (short)0x0110, (short)0x0200, + (short)0x0360, (short)0x04E0, (short)0x0608, (short)0x0738, (short)0x0838, (short)0x08D8, (short)0x0828, (short)0x0738, + (short)0x0600, (short)0x04A8, (short)0x02E0, (short)0x0130, (short)0xFFA0, (short)0xFF48, (short)0xFF10, (short)0xFEF0, + (short)0xFF30, (short)0xFFD0, (short)0x0090, (short)0x0090, (short)0x0070, (short)0x0060, (short)0xFFE8, (short)0xFF50, + (short)0xFEB8, (short)0xFE98, (short)0xFE88, (short)0xFE80, (short)0xFE58, (short)0xFE50, (short)0xFE58, (short)0xFDB0, + (short)0xFD08, (short)0xFC80, (short)0xFAF8, (short)0xF988, (short)0xF860, (short)0xF798, (short)0xF720, (short)0xF6E8, + (short)0xF728, (short)0xF7C0, (short)0xF8A8, (short)0xF8F8, (short)0xF960, (short)0xFA18, (short)0xFAC0, (short)0xFB58, + (short)0xFC18, (short)0xFCE0, (short)0xFDA0, (short)0xFE20, (short)0xFE88, (short)0xFEF8, (short)0xFEF0, (short)0xFEC8, + (short)0xFEA8, (short)0xFDE0, (short)0xFD10, (short)0xFC70, (short)0xFBA8, (short)0xFB10, (short)0xFAB8, (short)0xFAA0, + (short)0xFAD0, (short)0xFB18, (short)0xFA90, (short)0xFA18, (short)0xFA10, (short)0xFA80, (short)0xFB10, (short)0xFB88, + (short)0xFC90, (short)0xFDB8, (short)0xFEB8, (short)0xFF80, (short)0x0058, (short)0x0138, (short)0x0118, (short)0x00C8, + (short)0x00C0, (short)0xFF98, (short)0xFE30, (short)0xFD38, (short)0xFC68, (short)0xFB78, (short)0xFAB8, (short)0xFAE8, + (short)0xFB78, (short)0xFBD0, (short)0xFBE8, (short)0xFC18, (short)0xFC98, (short)0xFD28, (short)0xFD48, (short)0xFD68, + (short)0xFD68, (short)0xFD90, (short)0xFDB8, (short)0xFD90, (short)0xFD68, (short)0xFD78, (short)0xFCA0, (short)0xFB70, + (short)0xFAD0, (short)0xF9F0, (short)0xF870, (short)0xF748, (short)0xF748, (short)0xF770, (short)0xF748, (short)0xF720, + (short)0xF7A8, (short)0xF878, (short)0xF930, (short)0xF998, (short)0xFA38, (short)0xFC10, (short)0xFDA0, (short)0xFE70, + (short)0x0030, (short)0x0248, (short)0x03A0, (short)0x0568, (short)0x0738, (short)0x0870, (short)0x0960, (short)0x0A10, + (short)0x0A40, (short)0x0A28, (short)0x09B8, (short)0x08E8, (short)0x07E8, (short)0x06E0, (short)0x0588, (short)0x0430, + (short)0x0300, (short)0x0260, (short)0x01D0, (short)0x0118, (short)0xFFB0, (short)0xFE98, (short)0xFE18, (short)0xFDA0, + (short)0xFD08, (short)0xFCB8, (short)0xFCF8, (short)0xFD60, (short)0xFD90, (short)0xFD90, (short)0xFDD8, (short)0xFE50, + (short)0xFDA0, (short)0xFCE0, (short)0xFCC0, (short)0xFCE8, (short)0xFCB0, (short)0xFC60, (short)0xFC70, (short)0xFCB8, + (short)0xFCE0, (short)0xFD40, (short)0xFDD8, (short)0xFE68, (short)0xFF78, (short)0x0068, (short)0x0108, (short)0x0278, + (short)0x03A0, (short)0x0420, (short)0x0590, (short)0x0708, (short)0x07B8, (short)0x07D8, (short)0x0808, (short)0x0838, + (short)0x07D8, (short)0x06E8, (short)0x0600, (short)0x05B0, (short)0x0518, (short)0x0410, (short)0x02A0, (short)0x0198, + (short)0x00D0, (short)0x00C8, (short)0x00B0, (short)0x0068, (short)0x00C0, (short)0x0150, (short)0x0180, (short)0x0220, + (short)0x02D8, (short)0x0340, (short)0x0360, (short)0x0380, (short)0x0380, (short)0x0338, (short)0x02C8, (short)0x02B8, + (short)0x0280, (short)0x0200, (short)0x0100, (short)0x0098, (short)0x0080, (short)0x0020, (short)0xFFF0, (short)0x0000, + (short)0x0020, (short)0x0098, (short)0x0120, (short)0x0170, (short)0x0230, (short)0x02F0, (short)0x0350, (short)0x0480, + (short)0x05B8, (short)0x0650, (short)0x06A8, (short)0x0738, (short)0x0798, (short)0x07B0, (short)0x07C0, (short)0x0798, + (short)0x0668, (short)0x0598, (short)0x0530, (short)0x04C8, (short)0x0410, (short)0x0350, (short)0x0278, (short)0x01D8, + (short)0x0148, (short)0x0080, (short)0x0000, (short)0xFFC0, (short)0xFFD8, (short)0xFFA8, (short)0xFF60, (short)0xFF80, + (short)0x0018, (short)0x0070, (short)0xFFE0, (short)0xFF88, (short)0xFFC0, (short)0xFF38, (short)0xFE98, (short)0xFE50, + (short)0xFE10, (short)0xFDD8, (short)0xFD90, (short)0xFD30, (short)0xFDB8, (short)0xFE68, (short)0xFE70, (short)0xFE60, + (short)0xFE70, (short)0xFED0, (short)0xFF90, (short)0xFFE0, (short)0xFFF0, (short)0x00A8, (short)0x0168, (short)0x01D0, + (short)0x01F8, (short)0x0210, (short)0x0278, (short)0x0268, (short)0x0208, (short)0x0220, (short)0x01F8, (short)0x0198, + (short)0x0158, (short)0x0100, (short)0x00C0, (short)0x00A0, (short)0x0018, (short)0xFF98, (short)0xFF28, (short)0xFEC0, + (short)0xFE80, (short)0xFE60, (short)0xFD88, (short)0xFCF0, (short)0xFCC8, (short)0xFC70, (short)0xFC10, (short)0xFBC8, + (short)0xFBB0, (short)0xFBE8, (short)0xFBE8, (short)0xFB80, (short)0xFB88, (short)0xFB40, (short)0xFB18, (short)0xFB20, + (short)0xFAB8, (short)0xFA50, (short)0xFA50, (short)0xFAB8, (short)0xFAF8, (short)0xFB18, (short)0xFBB0, (short)0xFC88, + (short)0xFD10, (short)0xFD40, (short)0xFD98, (short)0xFE38, (short)0xFEE0, (short)0xFEF8, (short)0xFEF0, (short)0xFF18, + (short)0xFF18, (short)0xFF18, (short)0xFF68, (short)0xFF98, (short)0xFF98, (short)0xFFD0, (short)0xFFF8, (short)0x0048, + (short)0x0038, (short)0x0008, (short)0x0008, (short)0xFFE0, (short)0xFFB0, (short)0xFFB8, (short)0xFED0, (short)0xFE18, + (short)0xFE18, (short)0xFDF0, (short)0xFE38, (short)0xFE90, (short)0xFE90, (short)0xFDA8, (short)0xFD48, (short)0xFD70, + (short)0xFD68, (short)0xFD00, (short)0xFCB8, (short)0xFCB8, (short)0xFCF8, (short)0xFD00, (short)0xFC30, (short)0xFBD0, + (short)0xFC10, (short)0xFC20, (short)0xFBE0, (short)0xFBA8, (short)0xFC30, (short)0xFD00, (short)0xFD50, (short)0xFD90, + (short)0xFE10, (short)0xFEA8, (short)0xFF40, (short)0xFFA0, (short)0xFFD0, (short)0xFFC8, (short)0xFFC8, (short)0xFFD8, + (short)0xFFA0, (short)0xFF98, (short)0xFFB8, (short)0x0050, (short)0x00B8, (short)0x00B0, (short)0x01B0, (short)0x02E0, + (short)0x0318, (short)0x0330, (short)0x02E0, (short)0x02C8, (short)0x0278, (short)0x0150, (short)0x0050, (short)0xFFC0, + (short)0xFF88, (short)0xFF18, (short)0xFE90, (short)0xFE40, (short)0xFE30, (short)0xFDE8, (short)0xFDD0, (short)0xFD70, + (short)0xFD48, (short)0xFD10, (short)0xFC98, (short)0xFC38, (short)0xFC38, (short)0xFC78, (short)0xFC98, (short)0xFCF0, + (short)0xFDA8, (short)0xFE48, (short)0xFEC8, (short)0xFF30, (short)0xFF98, (short)0x0000, (short)0x0050, (short)0x0058, + (short)0x00A8, (short)0x00E8, (short)0x00D0, (short)0x0138, (short)0x01E0, (short)0x0218, (short)0x0208, (short)0x0230, + (short)0x0258, (short)0x0248, (short)0x02B0, (short)0x0318, (short)0x0330, (short)0x0358, (short)0x0380, (short)0x0378, + (short)0x0408, (short)0x0480, (short)0x0460, (short)0x03C8, (short)0x0318, (short)0x02B0, (short)0x01E8, (short)0x00B8, + (short)0xFFD8, (short)0xFF30, (short)0xFEC8, (short)0xFE60, (short)0xFE60, (short)0xFE78, (short)0xFE78, (short)0xFDC0, + (short)0xFD70, (short)0xFD50, (short)0xFD08, (short)0xFC88, (short)0xFC28, (short)0xFC98, (short)0xFD18, (short)0xFD60, + (short)0xFD60, (short)0xFDD8, (short)0xFE90, (short)0xFEE8, (short)0xFF10, (short)0xFF58, (short)0xFF90, (short)0xFFB8, + (short)0xFFE0, (short)0xFFF0, (short)0xFFF0, (short)0x00D0, (short)0x0190, (short)0x01C8, (short)0x0180, (short)0x0188, + (short)0x01B0, (short)0x0238, (short)0x0298, (short)0x02B8, (short)0x0268, (short)0x0258, (short)0x0258, (short)0x0230, + (short)0x0228, (short)0x0230, (short)0x0258, (short)0x0248, (short)0x01F8, (short)0x0150, (short)0x00C8, (short)0x0058, + (short)0x0058, (short)0x0038, (short)0x0000, (short)0xFF50, (short)0xFF00, (short)0xFEF8, (short)0xFE80, (short)0xFDB8, + (short)0xFD70, (short)0xFD00, (short)0xFC90, (short)0xFC40, (short)0xFC28, (short)0xFC58, (short)0xFC98, (short)0xFD10, + (short)0xFD78, (short)0xFDE0, (short)0xFE80, (short)0xFF08, (short)0xFF60, (short)0xFFD0, (short)0x0030, (short)0x0068, + (short)0x0110, (short)0x0198, (short)0x01C0, (short)0x0208, (short)0x0260, (short)0x0280, (short)0x0320, (short)0x0390, + (short)0x0398, (short)0x0410, (short)0x0488, (short)0x04A0, (short)0x0448, (short)0x0408, (short)0x03E0, (short)0x03C8, + (short)0x0398, (short)0x0350, (short)0x0308, (short)0x02C8, (short)0x0278, (short)0x01D8, (short)0x0148, (short)0x00E8, + (short)0x0040, (short)0xFFA0, (short)0xFF50, (short)0xFDC0, (short)0xFC88, (short)0xFC30, (short)0xFB88, (short)0xFAA8, + (short)0xFA50, (short)0xFA30, (short)0xFA40, (short)0xFA70, (short)0xFAB8, (short)0xFAE0, (short)0xFB28, (short)0xFB58, + (short)0xFB80, (short)0xFBB0, (short)0xFC00, (short)0xFC80, (short)0xFCF0, (short)0xFDB8, (short)0xFE58, (short)0xFED8, + (short)0x0008, (short)0x0100, (short)0x0180, (short)0x01D0, (short)0x0210, (short)0x0248, (short)0x0238, (short)0x0200, + (short)0x01D0, (short)0x02D0, (short)0x03A0, (short)0x03D8, (short)0x03C0, (short)0x03D8, (short)0x03F8, (short)0x0370, + (short)0x02C0, (short)0x0258, (short)0x01B8, (short)0x0120, (short)0x0090, (short)0x0088, (short)0x00A8, (short)0x00A8, + (short)0x0088, (short)0x0068, (short)0x0060, (short)0xFFE0, (short)0xFF00, (short)0xFE50, (short)0xFDC8, (short)0xFCF0, + (short)0xFC30, (short)0xFBB0, (short)0xFBD8, (short)0xFC20, (short)0xFC58, (short)0xFC30, (short)0xFC40, (short)0xFC78, + (short)0xFCC0, (short)0xFCE8, (short)0xFD10, (short)0xFD48, (short)0xFD88, (short)0xFDE8, (short)0xFF10, (short)0x0020, + (short)0x0110, (short)0x01B8, (short)0x0248, (short)0x02C0, (short)0x0358, (short)0x03B8, (short)0x03C8, (short)0x0320, + (short)0x0288, (short)0x0280, (short)0x0300, (short)0x0340, (short)0x0320, (short)0x0380, (short)0x03F8, (short)0x0418, + (short)0x0378, (short)0x02E0, (short)0x0288, (short)0x0280, (short)0x0238, (short)0x01D0, (short)0x0168, (short)0x0138, + (short)0x0110, (short)0x0140, (short)0x0148, (short)0x0150, (short)0x00A8, (short)0x0010, (short)0xFFB0, (short)0xFEB8, + (short)0xFDE0, (short)0xFD48, (short)0xFCE8, (short)0xFCA8, (short)0xFC78, (short)0xFC48, (short)0xFC50, (short)0xFC70, + (short)0xFCA8, (short)0xFCE8, (short)0xFD28, (short)0xFDD0, (short)0xFE70, (short)0xFED8, (short)0x0040, (short)0x0188, + (short)0x0258, (short)0x03C0, (short)0x04F0, (short)0x05B8, (short)0x0638, (short)0x0670, (short)0x0690, (short)0x0708, + (short)0x0708, (short)0x06B8, (short)0x0660, (short)0x0650, (short)0x0630, (short)0x05C8, (short)0x0578, (short)0x0548, + (short)0x0508, (short)0x0470, (short)0x03D0, (short)0x0350, (short)0x0278, (short)0x01A0, (short)0x00F8, (short)0x00B0, + (short)0x0078, (short)0x0030, (short)0xFFE8, (short)0xFFC8, (short)0xFFB8, (short)0xFED0, (short)0xFE08, (short)0xFD98, + (short)0xFC70, (short)0xFB60, (short)0xFAA8, (short)0xFA10, (short)0xF9B8, (short)0xF980, (short)0xF9A0, (short)0xFA00, + (short)0xFA68, (short)0xFB90, (short)0xFCB8, (short)0xFD98, (short)0xFE68, (short)0xFF18, (short)0xFFC0, (short)0x0078, + (short)0x00F8, (short)0x0218, (short)0x0320, (short)0x03C0, (short)0x0478, (short)0x0510, (short)0x0570, (short)0x05D8, + (short)0x05E0, (short)0x05B8, (short)0x0508, (short)0x0468, (short)0x03E0, (short)0x02F0, (short)0x0218, (short)0x0168, + (short)0x00F0, (short)0x0060, (short)0xFFD0, (short)0xFF58, (short)0xFEC0, (short)0xFE48, (short)0xFDB0, (short)0xFD58, + (short)0xFD38, (short)0xFCD8, (short)0xFC80, (short)0xFC50, (short)0xFC08, (short)0xFB48, (short)0xFA98, (short)0xF9F8, + (short)0xF8F8, (short)0xF810, (short)0xF7F8, (short)0xF818, (short)0xF848, (short)0xF8E8, (short)0xF9E0, (short)0xFB08, + (short)0xFC38, (short)0xFD10, (short)0xFDE8, (short)0xFF10, (short)0xFFD0, (short)0x0048, (short)0x00E0, (short)0x0160, + (short)0x01B8, (short)0x01C8, (short)0x01E0, (short)0x0200, (short)0x0228, (short)0x0240, (short)0x0240, (short)0x0240, + (short)0x0260, (short)0x0280, (short)0x0280, (short)0x02F0, (short)0x0370, (short)0x03C8, (short)0x03C8, (short)0x03A8, + (short)0x03A0, (short)0x02F8, (short)0x0220, (short)0x0150, (short)0x0098, (short)0xFFE0, (short)0xFF20, (short)0xFEA0, + (short)0xFE50, (short)0xFE18, (short)0xFD38, (short)0xFC60, (short)0xFBE0, (short)0xFAC8, (short)0xF9A0, (short)0xF8B8, + (short)0xF830, (short)0xF888, (short)0xF8B8, (short)0xF908, (short)0xFA80, (short)0xFBF8, (short)0xFD48, (short)0xFEC8, + (short)0x0040, (short)0x01B0, (short)0x0298, (short)0x0338, (short)0x03C0, (short)0x0470, (short)0x0520, (short)0x0588, + (short)0x0610, (short)0x0688, (short)0x06C8, (short)0x0670, (short)0x05E8, (short)0x0578, (short)0x0580, (short)0x0578, + (short)0x0528, (short)0x0498, (short)0x0408, (short)0x0390, (short)0x03F8, (short)0x0458, (short)0x0488, (short)0x0468, + (short)0x0450, (short)0x0458, (short)0x03A8, (short)0x02D0, (short)0x0210, (short)0x0158, (short)0x0088, (short)0xFFA8, + (short)0xFF00, (short)0xFE88, (short)0xFE30, (short)0xFD88, (short)0xFCB8, (short)0xFC28, (short)0xFB30, (short)0xF9F0, + (short)0xF8E8, (short)0xF890, (short)0xF890, (short)0xF8C0, (short)0xF978, (short)0xFA78, (short)0xFBE8, (short)0xFD20, + (short)0xFE28, (short)0xFF60, (short)0x00D8, (short)0x0220, (short)0x02F8, (short)0x0378, (short)0x03E0, (short)0x0438, + (short)0x0488, (short)0x0498, (short)0x04A8, (short)0x0480, (short)0x0440, (short)0x03C0, (short)0x02D8, (short)0x01E8, + (short)0x0140, (short)0x00D8, (short)0x0068, (short)0xFFE0, (short)0x0068, (short)0x0130, (short)0x0228, (short)0x0260, + (short)0x0278, (short)0x02D0, (short)0x02D8, (short)0x0290, (short)0x01E0, (short)0x00D0, (short)0xFFE0, (short)0xFEF8, + (short)0xFE08, (short)0xFD28, (short)0xFC88, (short)0xFBE0, (short)0xFB60, (short)0xFAD8, (short)0xFA08, (short)0xF978, + (short)0xF8E8, (short)0xF8B0, (short)0xF8B0, (short)0xF8D0, (short)0xF9D0, (short)0xFAF8, (short)0xFC18, (short)0xFDB0, + (short)0xFF38, (short)0x00A0, (short)0x01F8, (short)0x02F8, (short)0x03C0, (short)0x0460, (short)0x04B8, (short)0x04C8, + (short)0x04C8, (short)0x04C0, (short)0x0498, (short)0x0490, (short)0x0478, (short)0x0448, (short)0x0420, (short)0x03F8, + (short)0x0328, (short)0x0238, (short)0x01B0, (short)0x0170, (short)0x0128, (short)0x0090, (short)0x00E8, (short)0x01B8, + (short)0x02B8, (short)0x0280, (short)0x0218, (short)0x0218, (short)0x01F0, (short)0x0148, (short)0x0000, (short)0xFEC0, + (short)0xFE08, (short)0xFD70, (short)0xFCA0, (short)0xFBF0, (short)0xFBC0, (short)0xFBA0, (short)0xFB80, (short)0xFB18, + (short)0xFB28, (short)0xFB98, (short)0xFBC0, (short)0xFBD0, (short)0xFC08, (short)0xFC78, (short)0xFDC8, (short)0xFEC8, + (short)0xFF78, (short)0x00D0, (short)0x0238, (short)0x0360, (short)0x0398, (short)0x0360, (short)0x0368, (short)0x0380, + (short)0x0318, (short)0x0250, (short)0x0208, (short)0x0220, (short)0x0218, (short)0x01F0, (short)0x01C8, (short)0x0210, + (short)0x0270, (short)0x0270, (short)0x0240, (short)0x0290, (short)0x0310, (short)0x0360, (short)0x0340, (short)0x0310, + (short)0x0318, (short)0x0320, (short)0x02D8, (short)0x0240, (short)0x0158, (short)0x00A0, (short)0x0008, (short)0xFF30, + (short)0xFE50, (short)0xFDA8, (short)0xFD28, (short)0xFCC8, (short)0xFC60, (short)0xFBA8, (short)0xFB40, (short)0xFB10, + (short)0xFB18, (short)0xFB28, (short)0xFB48, (short)0xFB68, (short)0xFBA8, (short)0xFBF8, (short)0xFCB8, (short)0xFD78, + (short)0xFE00, (short)0xFE88, (short)0xFF30, (short)0xFF98, (short)0xFFC8, (short)0xFFE8, (short)0x0050, (short)0x00B0, + (short)0x00E0, (short)0x0040, (short)0xFF68, (short)0xFED8, (short)0xFEE8, (short)0xFEE0, (short)0xFE90, (short)0xFEA8, + (short)0xFF88, (short)0x0080, (short)0x0188, (short)0x0208, (short)0x0290, (short)0x0390, (short)0x0438, (short)0x0450, + (short)0x0428, (short)0x03F8, (short)0x03E0, (short)0x0388, (short)0x02E0, (short)0x0240, (short)0x0190, (short)0x00D0, + (short)0x0000, (short)0x0000, (short)0x0018, (short)0x00FF, (short)0x0068, (short)0x00FE, (short)0x00F8, (short)0x00FD +}; + +gsm_byte gsm_enc_gsmdata[] = { + 0xD5, 0x1F, 0x74, 0x21, 0xA0, 0x50, 0x40, 0xC9, 0x24, 0x7B, 0xFA, 0x6B, 0x52, 0xE0, 0xB6, 0xD6, + 0x8E, 0xB9, 0x2B, 0xAE, 0xE0, 0x8B, 0x23, 0x52, 0x3B, 0x13, 0x86, 0xE0, 0x14, 0x4A, 0x41, 0x44, + 0x32, 0xD3, 0xA1, 0x83, 0xA1, 0x1D, 0xA6, 0x80, 0xBA, 0xD2, 0x96, 0x26, 0xFB, 0x84, 0x80, 0x6D, + 0x9C, 0x25, 0x1D, 0x9B, 0xAA, 0xC0, 0xBB, 0x4C, 0x95, 0xB9, 0x53, 0xAE, 0xA0, 0xB6, 0xE4, 0x46, + 0x37, 0x1B, 0xD4, 0xA5, 0x7B, 0x1D, 0x22, 0x97, 0x00, 0xBA, 0xA5, 0x6D, 0xD2, 0xA1, 0x7E, 0xC0, + 0xB9, 0x25, 0xD2, 0xB4, 0x94, 0x9E, 0xE0, 0x3E, 0xDE, 0xED, 0xD6, 0xD2, 0xE2, 0xC0, 0xD7, 0x5D, + 0x8D, 0x59, 0xAC, 0xD3, 0xE4, 0x83, 0x95, 0x59, 0xC0, 0xA1, 0x48, 0xD2, 0x66, 0xC7, 0x2C, 0x9E, + 0xA0, 0x2A, 0xD3, 0xEE, 0x45, 0x1C, 0x80, 0xE0, 0x6B, 0x34, 0x8C, 0x4B, 0x29, 0xCB, 0x00, 0xBA, + 0xF6, 0x0D, 0x26, 0x9A, 0xD3, 0xA4, 0x82, 0x9D, 0x63, 0x7A, 0xC0, 0x67, 0x24, 0xBA, 0xD6, 0x7C, + 0xC2, 0xC0, 0x37, 0x20, 0x4F, 0x10, 0xE0, 0xC7, 0x80, 0x6A, 0x77, 0x63, 0xBE, 0x6B, 0x5A, 0xC0, + 0xB5, 0x34, 0xD1, 0x34, 0x9C, 0xD4, 0xE8, 0x56, 0xB2, 0x58, 0x5F, 0x00, 0xB7, 0xAF, 0x92, 0x12, + 0x90, 0xD5, 0xA4, 0x39, 0x23, 0x4E, 0x46, 0x87, 0x51, 0xAC, 0xD8, 0xDB, 0x6D, 0xCB, 0x17, 0x50, + 0x89, 0x7B, 0x44, 0x28, 0x03, 0x6B, 0xD5, 0xA9, 0x36, 0x36, 0xD9, 0x6B, 0xA8, 0x93, 0x3A, 0x96, + 0xEE, 0xFF, 0x67, 0x8B, 0x36, 0xDA, 0x09, 0xB4, 0x99, 0x67, 0x2B, 0x88, 0xE4, 0xB5, 0xA5, 0xDA, + 0x65, 0x47, 0xDA, 0x1E, 0x96, 0xFA, 0xEC, 0xD5, 0xA9, 0x45, 0x63, 0x1A, 0xCB, 0xC9, 0x48, 0x9D, + 0x83, 0x5F, 0x6F, 0xCB, 0x08, 0x1B, 0x97, 0xC9, 0x18, 0x0A, 0x63, 0xCB, 0xA6, 0xE1, 0x84, 0xF5, + 0x62, 0x61, 0x6A, 0x84, 0xDC, 0xB6, 0x37, 0x9E, 0xD6, 0xAB, 0x3C, 0x53, 0x93, 0xC1, 0x2A, 0xAA, + 0x81, 0x8D, 0x6B, 0x65, 0x60, 0xA8, 0xFB, 0x2E, 0x22, 0x59, 0x74, 0x61, 0xA6, 0x5D, 0x73, 0x94, + 0xF8, 0xE4, 0xC1, 0x46, 0x26, 0x5E, 0x8A, 0x86, 0xED, 0xD4, 0xA6, 0x2D, 0x57, 0x6B, 0xBE, 0xE8, + 0x58, 0xDA, 0x3D, 0x98, 0x99, 0xBE, 0xA8, 0xC2, 0xDB, 0x6A, 0x2E, 0x51, 0x62, 0xE5, 0x80, 0x58, + 0x76, 0xB8, 0xE4, 0x6C, 0x84, 0xCA, 0x98, 0x06, 0x0B, 0xFC, 0xD2, 0x66, 0x7C, 0x62, 0x3A, 0x5B, + 0xC5, 0xDF, 0x7D, 0x75, 0x49, 0x1E, 0x52, 0xC7, 0x55, 0xF7, 0x84, 0xA6, 0xDA, 0x5D, 0x43, 0x26, + 0x85, 0x98, 0xD8, 0x8F, 0xB6, 0xC5, 0x28, 0xEB, 0x3E, 0x75, 0x04, 0xD2, 0x27, 0xBA, 0x2A, 0x2B, + 0xB7, 0x03, 0x13, 0x45, 0x35, 0x1B, 0x78, 0x5F, 0xC3, 0xBA, 0xDB, 0xAE, 0x27, 0xC2, 0x5E, 0xA4, + 0x50, 0x8C, 0x8A, 0xBB, 0x4F, 0x60, 0xC3, 0xEE, 0x41, 0x46, 0x4A, 0xDF, 0xD2, 0x27, 0xB2, 0xAD, + 0xEB, 0x5F, 0x43, 0x4C, 0x6A, 0x09, 0x2A, 0xCC, 0xB7, 0x47, 0x2A, 0xB9, 0x91, 0xB6, 0xD4, 0x5B, + 0x25, 0x58, 0xD8, 0xFD, 0x46, 0x95, 0x5A, 0xC3, 0x27, 0x5B, 0x3F, 0xFB, 0x12, 0xD2, 0x26, 0xC3, + 0xA9, 0xA1, 0xB6, 0xA2, 0xCB, 0x1B, 0xD0, 0x73, 0xE4, 0xBA, 0xA1, 0xE9, 0x05, 0xBE, 0x79, 0x23, + 0xA4, 0xC2, 0x3A, 0x4B, 0x11, 0xE5, 0x68, 0xC4, 0xC1, 0xBA, 0xC1, 0xCC, 0x8B, 0x02, 0xD2, 0x63, + 0x6C, 0xEE, 0x19, 0x5E, 0xE1, 0xB6, 0x4C, 0x1A, 0xB4, 0x5E, 0xF0, 0xC2, 0x27, 0x20, 0x55, 0xBD, + 0x6D, 0x64, 0xE1, 0xC7, 0x45, 0xA9, 0x65, 0x6D, 0x7D, 0x42, 0x56, 0xD8, 0xB2, 0xB6, 0xEC, 0xD3, + 0x61, 0x5B, 0x62, 0x61, 0x60, 0xA1, 0x5B, 0xD6, 0x15, 0x29, 0x09, 0x6C, 0xA1, 0x3E, 0xAD, 0x65, + 0x34, 0xC3, 0xC0, 0xC1, 0x22, 0x6D, 0x4C, 0x57, 0x10, 0xDB, 0x41, 0xD2, 0xE1, 0x77, 0x64, 0xF7, + 0xD3, 0x21, 0x73, 0xA9, 0x29, 0x58, 0xC1, 0xA1, 0x5A, 0x52, 0xB7, 0x32, 0x64, 0xC1, 0x67, 0x42, + 0x74, 0x2C, 0xDC, 0x61, 0x61, 0x65, 0x8B, 0xCB, 0x04, 0xE5, 0x60, 0xC1, 0xC9, 0x5E, 0x8E, 0x36, + 0x83, 0xD2, 0xA2, 0x83, 0xA9, 0xD9, 0xCD, 0x21, 0xB9, 0x25, 0xCD, 0xE6, 0x1D, 0x60, 0xA1, 0xB4, + 0xAA, 0x8F, 0xBA, 0x75, 0xC3, 0x01, 0x0B, 0x3B, 0x51, 0xDB, 0xEC, 0x62, 0xE1, 0x38, 0xCD, 0x40, + 0x3B, 0xD3, 0xD2, 0x26, 0x94, 0x29, 0xD2, 0x61, 0x21, 0x6B, 0x4A, 0x8D, 0x24, 0xB5, 0xBB, 0x21, + 0x12, 0xA5, 0x99, 0xA5, 0x1A, 0xCA, 0xA1, 0xEF, 0x5D, 0xAA, 0xAE, 0xD3, 0x64, 0xE1, 0xA3, 0x6B, + 0xAE, 0x35, 0x39, 0xD2, 0x66, 0x73, 0xB6, 0x90, 0xC6, 0xC1, 0x32, 0xD1, 0xBA, 0xC9, 0x25, 0x65, + 0x81, 0xA8, 0xD2, 0xB1, 0xE7, 0x18, 0xBE, 0xC0, 0xFC, 0xE4, 0x85, 0xB5, 0x06, 0xB4, 0x81, 0x35, + 0x46, 0xB6, 0xC8, 0x9B +}; + +#endif /* end of include guard: DATA_H */ diff --git a/baseline/source/gsm_enc/gsm_enc.c b/baseline/source/gsm_enc/gsm_enc.c new file mode 100644 index 0000000..cdac899 --- /dev/null +++ b/baseline/source/gsm_enc/gsm_enc.c @@ -0,0 +1,2072 @@ +/* gsm_enc_encode.c */ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +#include "../extra.h" +#include "private.h" + +/* + * Prototypes from add.c + */ + +extern word gsm_enc_div (word num, word denum); + +extern word gsm_enc_sub (word a, word b); + +extern word gsm_enc_norm ( longword a ); + +extern word gsm_enc_asl (word a, int n); + +extern word gsm_enc_asr (word a, int n); + +/* + * Inlined functions from add.h + */ + +#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) + +# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_L_ADD(a, b) \ + ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= (ulongword)MAX_LONGWORD \ + ? MAX_LONGWORD : a + b)) + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +#define saturate(x) \ + ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) + +/* Use these if necessary: + +# define GSM_MULT_R(a, b) gsm_enc_mult_r(a, b) +# define GSM_MULT(a, b) gsm_enc_mult(a, b) +# define GSM_L_MULT(a, b) gsm_enc_L_mult(a, b) + +# define GSM_L_ADD(a, b) gsm_enc_L_add(a, b) +# define GSM_ADD(a, b) gsm_enc_add(a, b) +# define GSM_SUB(a, b) gsm_enc_sub(a, b) + +# define GSM_ABS(a) gsm_enc_abs(a) +*/ + +/* + * More prototypes from implementations.. + */ +extern void gsm_enc_Gsm_Coder ( + struct gsm_state * S, + word * s, /* [0..159] samples IN */ + word * LARc, /* [0..7] LAR coefficients OUT */ + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */); + +extern void gsm_enc_Gsm_Long_Term_Predictor ( /* 4x for 160 samples */ + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + word * e, /* [0..40] OUT */ + word * dpp, /* [0..40] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */); + +extern void gsm_enc_Gsm_LPC_Analysis ( + word * s, /* 0..159 signals IN/OUT */ + word * LARc); /* 0..7 LARc's OUT */ + +extern void gsm_enc_Gsm_Preprocess ( + struct gsm_state * S, + word * s, word * so); + +extern void gsm_enc_Gsm_Short_Term_Analysis_Filter ( + struct gsm_state * S, + word * LARc, /* coded log area ratio [0..7] IN */ + word * d /* st res. signal [0..159] IN/OUT */); + +void gsm_enc_Gsm_RPE_Encoding ( + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc); /* [0..12] OUT */ + + +/**************** end #include "private.h" **********************************/ + +/* + * Interface + */ + +typedef struct gsm_state * gsm; +typedef short gsm_signal; /* signed 16 bit */ +typedef unsigned char gsm_byte; +typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ + +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +#define GSM_PATCHLEVEL 6 +#define GSM_MINOR 0 +#define GSM_MAJOR 1 + +#include "data.h" + +extern void gsm_enc_encode (gsm, gsm_signal *, gsm_byte *); + +extern int gsm_enc_explode (gsm, gsm_byte *, gsm_signal *); +extern void gsm_enc_implode (gsm, gsm_signal *, gsm_byte *); + + +/******************* end #include "gsm.h" **********************************/ + +#define SAMPLES 20 + +/* + Forward declaration of global variables +*/ + +struct gsm_state gsm_enc_state; +gsm gsm_enc_state_ptr; +volatile int gsm_enc_result; + + +/* add.c */ + +word gsm_enc_sub (word a, word b) +{ + longword diff = (longword)a - (longword)b; + return saturate(diff); +} + + +unsigned char gsm_enc_bitoff[ 256 ] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void gsm_enc_encode (gsm s, gsm_signal * source, gsm_byte * c) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + gsm_enc_Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); + + + /* variable size + + GSM_MAGIC 4 + + LARc[0] 6 + LARc[1] 6 + LARc[2] 5 + LARc[3] 5 + LARc[4] 4 + LARc[5] 4 + LARc[6] 3 + LARc[7] 3 + + Nc[0] 7 + bc[0] 2 + Mc[0] 2 + xmaxc[0] 6 + xmc[0] 3 + xmc[1] 3 + xmc[2] 3 + xmc[3] 3 + xmc[4] 3 + xmc[5] 3 + xmc[6] 3 + xmc[7] 3 + xmc[8] 3 + xmc[9] 3 + xmc[10] 3 + xmc[11] 3 + xmc[12] 3 + + Nc[1] 7 + bc[1] 2 + Mc[1] 2 + xmaxc[1] 6 + xmc[13] 3 + xmc[14] 3 + xmc[15] 3 + xmc[16] 3 + xmc[17] 3 + xmc[18] 3 + xmc[19] 3 + xmc[20] 3 + xmc[21] 3 + xmc[22] 3 + xmc[23] 3 + xmc[24] 3 + xmc[25] 3 + + Nc[2] 7 + bc[2] 2 + Mc[2] 2 + xmaxc[2] 6 + xmc[26] 3 + xmc[27] 3 + xmc[28] 3 + xmc[29] 3 + xmc[30] 3 + xmc[31] 3 + xmc[32] 3 + xmc[33] 3 + xmc[34] 3 + xmc[35] 3 + xmc[36] 3 + xmc[37] 3 + xmc[38] 3 + + Nc[3] 7 + bc[3] 2 + Mc[3] 2 + xmaxc[3] 6 + xmc[39] 3 + xmc[40] 3 + xmc[41] 3 + xmc[42] 3 + xmc[43] 3 + xmc[44] 3 + xmc[45] 3 + xmc[46] 3 + xmc[47] 3 + xmc[48] 3 + xmc[49] 3 + xmc[50] 3 + xmc[51] 3 + */ + + + *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF); + *c++ = ((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F); + *c++ = ((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7); + *c++ = ((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3); + *c++ = ((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7); + *c++ = ((Nc[0] & 0x7F) << 1) + | ((bc[0] >> 1) & 0x1); + *c++ = ((bc[0] & 0x1) << 7) + | ((Mc[0] & 0x3) << 5) + | ((xmaxc[0] >> 1) & 0x1F); + *c++ = ((xmaxc[0] & 0x1) << 7) + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1); + *c++ = ((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7); + *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3); + *c++ = ((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1); + *c++ = ((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7); + *c++ = ((Nc[1] & 0x7F) << 1) + | ((bc[1] >> 1) & 0x1); + *c++ = ((bc[1] & 0x1) << 7) + | ((Mc[1] & 0x3) << 5) + | ((xmaxc[1] >> 1) & 0x1F); + *c++ = ((xmaxc[1] & 0x1) << 7) + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1); + *c++ = ((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7); + *c++ = ((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3); + *c++ = ((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1); + *c++ = ((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7); + *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ + | ((bc[2] >> 1) & 0x1); + *c++ = ((bc[2] & 0x1) << 7) + | ((Mc[2] & 0x3) << 5) + | ((xmaxc[2] >> 1) & 0x1F); + *c++ = ((xmaxc[2] & 0x1) << 7) + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1); + *c++ = ((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7); + *c++ = ((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3); + *c++ = ((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1); + *c++ = ((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7); + *c++ = ((Nc[3] & 0x7F) << 1) + | ((bc[3] >> 1) & 0x1); + *c++ = ((bc[3] & 0x1) << 7) + | ((Mc[3] & 0x3) << 5) + | ((xmaxc[3] >> 1) & 0x1F); + *c++ = ((xmaxc[3] & 0x1) << 7) + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1); + *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7); + *c++ = ((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3); + *c++ = ((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1); + *c++ = ((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7); + +} + +/* decode.c */ +/* + * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER + */ + +/* code.c */ +void gsm_enc_Gsm_Coder ( + + struct gsm_state * S, + + word * s, /* [0..159] samples IN */ + +/* + * The RPE-LTD coder works on a frame by frame basis. The length of + * the frame is equal to 160 samples. Some computations are done + * once per frame to produce at the output of the coder the + * LARc[1..8] parameters which are the coded LAR coefficients and + * also to realize the inverse filtering operation for the entire + * frame (160 samples of signal d[0..159]). These parts produce at + * the output of the coder: + */ + + word * LARc, /* [0..7] LAR coefficients OUT */ + +/* + * Procedure 4.2.11 to 4.2.18 are to be executed four times per + * frame. That means once for each sub-segment RPE-LTP analysis of + * 40 samples. These parts produce at the output of the coder: + */ + + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */ +) +{ + int k; + word * dp = S->dp0 + 120; /* [ -120...-1 ] */ + word * dpp = dp; /* [ 0...39 ] */ + + static word e [50] = {0}; + + word so[160]; + + gsm_enc_Gsm_Preprocess (S, s, so); + gsm_enc_Gsm_LPC_Analysis (so, LARc); + gsm_enc_Gsm_Short_Term_Analysis_Filter (S, LARc, so); + + _Pragma("loopbound min 4 max 4") + for (k = 0; k <= 3; k++, xMc += 13) { + + gsm_enc_Gsm_Long_Term_Predictor ( + so+k*40, /* d [0..39] IN */ + dp, /* dp [-120..-1] IN */ + e + 5, /* e [0..39] OUT */ + dpp, /* dpp [0..39] OUT */ + Nc++, + bc++); + + gsm_enc_Gsm_RPE_Encoding ( + e + 5, /* e ][0..39][ IN/OUT */ + xmaxc++, Mc++, xMc ); + /* + * gsm_enc_Gsm_Update_of_reconstructed_short_time_residual_signal + * ( dpp, e + 5, dp ); + */ + + { int i; + longword ltmp; + _Pragma("loopbound min 40 max 40") + for (i = 0; i <= 39; i++) { + dp[ i ] = GSM_ADD( e[5 + i], dpp[i] ); + } + } + + dp += 40; + dpp += 40; + + } +// //(void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), +// // 120 * sizeof(*S->dp0) ); +} + +/* rpe.c */ +/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION + */ + +/* 4.2.13 */ + +void gsm_enc_Weighting_filter ( + word * e, /* signal [-5..0.39.44] IN */ + word * x /* signal [0..39] OUT */ +) +/* + * The coefficients of the weighting filter are stored in a table + * (see table 4.4). The following scaling is used: + * + * H[0..10] = integer( real_H[ 0..10] * 8192 ); + */ +{ + /* word wt[ 50 ]; */ + + longword L_result; + int k /* , i */ ; + + /* Initialization of a temporary working array wt[0...49] + */ + + /* for (k = 0; k <= 4; k++) wt[k] = 0; + * for (k = 5; k <= 44; k++) wt[k] = *e++; + * for (k = 45; k <= 49; k++) wt[k] = 0; + * + * (e[-5..-1] and e[40..44] are allocated by the caller, + * are initially zero and are not written anywhere.) + */ + e -= 5; + + /* Compute the signal x[0..39] + */ + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) { + + L_result = 8192 >> 1; + + /* for (i = 0; i <= 10; i++) { + * L_temp = GSM_L_MULT( wt[k+i], gsm_enc_H[i] ); + * L_result = GSM_L_ADD( L_result, L_temp ); + * } + */ + +#undef STEP +#define STEP( i, H ) (e[ k + i ] * (longword)H) + + /* Every one of these multiplications is done twice -- + * but I don't see an elegant way to optimize this. + * Do you? + */ + +#ifdef STUPID_COMPILER + L_result += STEP( 0, -134 ) ; + L_result += STEP( 1, -374 ) ; + /* + STEP( 2, 0 ) */ + L_result += STEP( 3, 2054 ) ; + L_result += STEP( 4, 5741 ) ; + L_result += STEP( 5, 8192 ) ; + L_result += STEP( 6, 5741 ) ; + L_result += STEP( 7, 2054 ) ; + /* + STEP( 8, 0 ) */ + L_result += STEP( 9, -374 ) ; + L_result += STEP( 10, -134 ) ; +#else + L_result += + STEP( 0, -134 ) + + STEP( 1, -374 ) + /* + STEP( 2, 0 ) */ + + STEP( 3, 2054 ) + + STEP( 4, 5741 ) + + STEP( 5, 8192 ) + + STEP( 6, 5741 ) + + STEP( 7, 2054 ) + /* + STEP( 8, 0 ) */ + + STEP( 9, -374 ) + + STEP(10, -134 ) + ; +#endif + /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) + * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) + * + * x[k] = SASR( L_result, 16 ); + */ + + /* 2 adds vs. >>16 => 14, minus one shift to compensate for + * those we lost when replacing L_MULT by '*'. + */ + + L_result = SASR( L_result, 13 ); + x[k] = ( L_result < MIN_WORD ? MIN_WORD + : (L_result > MAX_WORD ? MAX_WORD : L_result )); + } +} + +/* 4.2.14 */ + +void gsm_enc_RPE_grid_selection ( + word * x, /* [0..39] IN */ + word * xM, /* [0..12] OUT */ + word * Mc_out /* OUT */ +) +/* + * The signal x[0..39] is used to select the RPE grid which is + * represented by Mc. + */ +{ + /* word temp1; */ + int /* m, */ i; + longword L_result, L_temp; + longword EM; /* xxx should be L_EM? */ + word Mc; + + longword L_common_0_3; + + Mc = 0; + +#undef STEP +#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ + L_result += L_temp * L_temp; + + /* common part of 0 and 3 */ + + L_result = 0; + STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); + STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); + STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); + L_common_0_3 = L_result; + + /* i = 0 */ + + STEP( 0, 0 ); + L_result <<= 1; /* implicit in L_MULT */ + EM = L_result; + + /* i = 1 */ + + L_result = 0; + STEP( 1, 0 ); + STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); + STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); + STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 1; + EM = L_result; + } + + /* i = 2 */ + + L_result = 0; + STEP( 2, 0 ); + STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); + STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); + STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 2; + EM = L_result; + } + + /* i = 3 */ + + L_result = L_common_0_3; + STEP( 3, 12 ); + L_result <<= 1; + if (L_result > EM) { + Mc = 3; + } + + /**/ + + /* Down-sampling by a factor 3 to get the selected xM[0..12] + * RPE sequence. + */ + _Pragma("loopbound min 13 max 13") + for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; + *Mc_out = Mc; + +} + +/* 4.12.15 */ + +void gsm_enc_APCM_quantization_xmaxc_to_exp_mant ( + word xmaxc, /* IN */ + word * exp_out, /* OUT */ + word * mant_out ) /* OUT */ +{ + word exp, mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + exp = 0; + if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; + mant = xmaxc - (exp << 3); + + if (mant == 0) { + exp = -4; + mant = 7; + } + else { + _Pragma("loopbound min 0 max 3") + while (mant <= 7) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; + +} + +void gsm_enc_APCM_quantization ( + word * xM, /* [0..12] IN */ + + word * xMc, /* [0..12] OUT */ + word * mant_out, /* OUT */ + word * exp_out, /* OUT */ + word * xmaxc_out /* OUT */ +) +{ + int i, itest; + + word xmax, xmaxc, temp, temp1, temp2; + word exp, mant; + + + /* Find the maximum absolute value xmax of xM[0..12]. + */ + + xmax = 0; + + _Pragma("loopbound min 13 max 13") + for (i = 0; i <= 12; i++) { + temp = xM[i]; + temp = GSM_ABS(temp); + if (temp > xmax) xmax = temp; + } + + /* Qantizing and coding of xmax to get xmaxc. + */ + + exp = 0; + temp = SASR( xmax, 9 ); + itest = 0; + + _Pragma("loopbound min 6 max 6") + for (i = 0; i <= 5; i++) { + + itest |= (temp <= 0); + temp = SASR( temp, 1 ); + + if (itest == 0) exp++; // exp = add (exp, 1) + } + + temp = exp + 5; + + //xmaxc = gsm_enc_add( SASR(xmax, temp), exp << 3 ); + xmaxc = saturate( ( SASR(xmax, temp) + (exp << 3) )); + + /* Quantizing and coding of the xM[0..12] RPE sequence + * to get the xMc[0..12] + */ + + gsm_enc_APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); + + /* This computation uses the fact that the decoded version of xmaxc + * can be calculated by using the exponent and the mantissa part of + * xmaxc (logarithmic table). + * So, this method avoids any division and uses only a scaling + * of the RPE samples by a function of the exponent. A direct + * multiplication by the inverse of the mantissa (NRFAC[0..7] + * found in table 4.5) gives the 3 bit coded version xMc[0..12] + * of the RPE samples. + */ + + + /* Direct computation of xMc[0..12] using table 4.5 + */ + + + temp1 = 6 - exp; /* normalization by the exponent */ + temp2 = gsm_enc_NRFAC[ mant ]; /* inverse mantissa */ + + _Pragma("loopbound min 13 max 13") + for (i = 0; i <= 12; i++) { + + temp = xM[i] << temp1; + temp = GSM_MULT( temp, temp2 ); + temp = SASR(temp, 12); + xMc[i] = temp + 4; /* see note below */ + } + + /* NOTE: This equation is used to make all the xMc[i] positive. + */ + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; + +} + +/* 4.2.16 */ + +void gsm_enc_APCM_inverse_quantization ( + word * xMc, /* [0..12] IN */ + word mant, + word exp, + word * xMp) /* [0..12] OUT */ +/* + * This part is for decoding the RPE sequence of coded xMc[0..12] + * samples to obtain the xMp[0..12] array. Table 4.6 is used to get + * the mantissa of xmaxc (FAC[0..7]). + */ +{ + int i; + word temp, temp1, temp2, temp3; + longword ltmp; + + temp1 = gsm_enc_FAC[ mant ]; /* see 4.2-15 for mant */ + temp2 = gsm_enc_sub( 6, exp ); /* see 4.2-15 for exp */ + temp3 = gsm_enc_asl( 1, gsm_enc_sub( temp2, 1 )); + + _Pragma("loopbound min 13 max 13") + for (i = 13; i--;) { + + /* temp = gsm_enc_sub( *xMc++ << 1, 7 ); */ + temp = (*xMc++ << 1) - 7; /* restore sign */ + + temp <<= 12; /* 16 bit signed */ + temp = GSM_MULT_R( temp1, temp ); + temp = GSM_ADD( temp, temp3 ); + *xMp++ = gsm_enc_asr( temp, temp2 ); + } +} + +/* 4.2.17 */ + +void gsm_enc_RPE_grid_positioning ( + word Mc, /* grid position IN */ + word * xMp, /* [0..12] IN */ + word * ep /* [0..39] OUT */ +) +/* + * This procedure computes the reconstructed long term residual signal + * ep[0..39] for the LTP analysis filter. The inputs are the Mc + * which is the grid position selection and the xMp[0..12] decoded + * RPE samples which are upsampled by a factor of 3 by inserting zero + * values. + */ +{ + int i = 13; + + // + // TODO: rewritten Duff's device for WCET analysis! + // + switch (Mc) { + case 3: *ep++ = 0; + case 2: *ep++ = 0; + case 1: *ep++ = 0; + case 0: *ep++ = *xMp++; + i--; + } + + _Pragma("loopbound min 12 max 12") + do { + *ep++ = 0; + *ep++ = 0; + *ep++ = *xMp++; + } while (--i); + + _Pragma("loopbound min 0 max 3") + while (++Mc < 4) *ep++ = 0; + +} +/* +{ + int i = 13; + + // + //TODO: removed for WCET analysis +//_Pragma("marker outside") + switch (Mc) { + case 3: *ep++ = 0; + case 2: + _Pragma("loopbound min 13 max 13") + do { + *ep++ = 0; + case 1: *ep++ = 0; + case 0: + //_Pragma("marker inside") + *ep++ = *xMp++; + } while (--i); + } + + //_Pragma("flowrestriction 1*inside <= 13*outside") + + _Pragma("loopbound min 0 max 3") + while (++Mc < 4) *ep++ = 0; + +} +*/ + +/* 4.2.18 */ + +/* This procedure adds the reconstructed long term residual signal + * ep[0..39] to the estimated signal dpp[0..39] from the long term + * analysis filter to compute the reconstructed short term residual + * signal dp[-40..-1]; also the reconstructed short term residual + * array dp[-120..-41] is updated. + */ + +#if 0 /* Has been inlined in code.c */ +void gsm_enc_Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp) /* [-120...-1] IN/OUT */ +{ + int k; + + for (k = 0; k <= 79; k++) + dp[ -120 + k ] = dp[ -80 + k ]; + + for (k = 0; k <= 39; k++) + dp[ -40 + k ] = gsm_enc_add( ep[k], dpp[k] ); +} +#endif /* Has been inlined in code.c */ + +void gsm_enc_Gsm_RPE_Encoding ( + + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc) /* [0..12] OUT */ +{ + word x[40]; + word xM[13], xMp[13]; + word mant, exp; + + gsm_enc_Weighting_filter(e, x); + gsm_enc_RPE_grid_selection(x, xM, Mc); + + gsm_enc_APCM_quantization( xM, xMc, &mant, &exp, xmaxc); + gsm_enc_APCM_inverse_quantization( xMc, mant, exp, xMp); + + gsm_enc_RPE_grid_positioning( *Mc, xMp, e ); + +} + +/* long_term.c */ +#ifdef USE_TABLE_MUL + +unsigned int umul_table[ 513 ][ 256 ]; + +# define umul(x9, x15) \ + ((int)(umul_table[x9][x15 & 0x0FF] + (umul_table[x9][ x15 >> 8 ] << 8))) + +# define table_mul(a, b) \ + ( (a < 0) ? ((b < 0) ? umul(-a, -b) : -umul(-a, b)) \ + : ((b < 0) ? -umul(a, -b) : umul(a, b))) + +#endif /* USE_TABLE_MUL */ + + + +/* + * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION + */ + + +/* + * This procedure computes the LTP gain (bc) and the LTP lag (Nc) + * for the long term analysis filter. This is done by calculating a + * maximum of the cross-correlation function between the current + * sub-segment short term residual signal d[0..39] (output of + * the short term analysis filter; for simplification the index + * of this array begins at 0 and ends at 39 for each sub-segment of the + * RPE-LTP analysis) and the previous reconstructed short term + * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be + * performed to avoid overflow. + */ + + /* This procedure exists in four versions. First, the two integer + * versions with or without table-multiplication (as one function); + * then, the two floating point versions (as another function), with + * or without scaling. + */ + +#ifndef USE_FLOAT_MUL + +void gsm_enc_Calculation_of_the_LTP_parameters ( + word * d, /* [0..39] IN */ + word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_max, L_power; + word R, S, dmax, scal; + word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax != 0) + temp = gsm_enc_norm( (longword)dmax << 16 ); + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + + /* Initialization of a working array wt + */ + + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + _Pragma("loopbound min 81 max 81") + for (lambda = 40; lambda <= 120; lambda++) { + +# undef STEP +# ifdef USE_TABLE_MUL +# define STEP(k) (table_mul(wt[k], dp[k - lambda])) +# else +# define STEP(k) (wt[k] * dp[k - lambda]) +# endif + + longword L_result; + + L_result = STEP(0) ; L_result += STEP(1) ; + L_result += STEP(2) ; L_result += STEP(3) ; + L_result += STEP(4) ; L_result += STEP(5) ; + L_result += STEP(6) ; L_result += STEP(7) ; + L_result += STEP(8) ; L_result += STEP(9) ; + L_result += STEP(10) ; L_result += STEP(11) ; + L_result += STEP(12) ; L_result += STEP(13) ; + L_result += STEP(14) ; L_result += STEP(15) ; + L_result += STEP(16) ; L_result += STEP(17) ; + L_result += STEP(18) ; L_result += STEP(19) ; + L_result += STEP(20) ; L_result += STEP(21) ; + L_result += STEP(22) ; L_result += STEP(23) ; + L_result += STEP(24) ; L_result += STEP(25) ; + L_result += STEP(26) ; L_result += STEP(27) ; + L_result += STEP(28) ; L_result += STEP(29) ; + L_result += STEP(30) ; L_result += STEP(31) ; + L_result += STEP(32) ; L_result += STEP(33) ; + L_result += STEP(34) ; L_result += STEP(35) ; + L_result += STEP(36) ; L_result += STEP(37) ; + L_result += STEP(38) ; L_result += STEP(39) ; + + if (L_result > L_max) { + + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + _Pragma("loopbound min 40 max 40") + for (k = 0; k <= 39; k++) { + + longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_enc_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + _Pragma("loopbound min 3 max 3") + for (bc = 0; bc <= 2; bc++) + /* Replaced by macro function. */ + //if (R <= gsm_enc_mult(S, gsm_enc_DLB[bc])) + if (R <= GSM_MULT(S, gsm_enc_DLB[bc])) + break; + + *bc_out = bc; +} + +#else /* USE_FLOAT_MUL */ + +void gsm_enc_Calculation_of_the_LTP_parameters ( + word * d, /* [0..39] IN */ + word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + temp = gsm_enc_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + float *lp = dp_float - lambda; + + float W; + float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + float E; + float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_enc_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + // Replaced by macro function. + //for (bc = 0; bc <= 2; bc++) if (R <= gsm_enc_mult(S, gsm_enc_DLB[bc])) break; + for (bc = 0; bc <= 2; bc++) if (R <= GSM_MULT(S, gsm_enc_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* USE_FLOAT_MUL */ + + +/* 4.2.12 */ + +void gsm_enc_Long_term_analysis_filtering ( + word bc, /* IN */ + word Nc, /* IN */ + word * dp, /* previous d [-120..-1] IN */ + word * d, /* d [0..39] IN */ + word * dpp, /* estimate [0..39] OUT */ + word * e /* long term res. signal [0..39] OUT */ +) +/* + * In this part, we have to decode the bc parameter to compute + * the samples of the estimate dpp[0..39]. The decoding of bc needs the + * use of table 4.3b. The long term residual signal e[0..39] + * is then calculated to be fed to the RPE encoding section. + */ +{ + int k; + longword ltmp; + +# undef STEP +# define STEP(BP) \ + _Pragma("loopbound min 40 max 40") \ + for (k = 0; k <= 39; k++) { \ + dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ + e[k] = GSM_SUB( d[k], dpp[k] ); \ + } + + switch (bc) { + case 0: STEP( 3277 ); break; + case 1: STEP( 11469 ); break; + case 2: STEP( 21299 ); break; + case 3: STEP( 32767 ); break; + } +} + +void gsm_enc_Gsm_Long_Term_Predictor ( + + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + + word * e, /* [0..39] OUT */ + word * dpp, /* [0..39] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */ +) +{ + + gsm_enc_Calculation_of_the_LTP_parameters( d, dp, bc, Nc ); + + gsm_enc_Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); +} + +/* short_term.c */ +/* + * SHORT TERM ANALYSIS FILTERING SECTION + */ + +/* 4.2.8 */ + +void gsm_enc_Decoding_of_the_coded_Log_Area_Ratios ( + word * LARc, /* coded log area ratio [0..7] IN */ + word * LARpp) /* out: decoded .. */ +{ + word temp1 /* , temp2 */; + long ltmp; /* for GSM_ADD */ + + /* This procedure requires for efficient implementation + * two tables. + * + * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) + * MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] + */ + +#undef STEP +#define STEP( B, MIC, INVA ) \ + temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ + temp1 = GSM_SUB( temp1, (B >= 0 ? B << 1 : -((-B) << 1))); \ + temp1 = GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = GSM_ADD( temp1, temp1 ); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( -2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( -1792, -8, 17476 ); + STEP( -341, -4, 31454 ); + STEP( -1144, -4, 29708 ); + + /* NOTE: the addition of *MIC is used to restore + * the sign of *LARc. + */ +} + +/* 4.2.9 */ +/* Computation of the quantized reflection coefficients + */ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] + */ + +/* + * Within each frame of 160 analyzed speech samples the short term + * analysis and synthesis filters operate with four different sets of + * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) + * and the actual set of decoded LARs (LARpp(j)) + * + * (Initial value: LARpp(j-1)[1..8] = 0.) + */ + +void gsm_enc_Coefficients_0_12 ( + word * LARpp_j_1, + word * LARpp_j, + word * LARp) +{ + int i; + longword ltmp; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); + } +} + +void gsm_enc_Coefficients_13_26 ( + word * LARpp_j_1, + word * LARpp_j, + word * LARp) +{ + int i; + longword ltmp; + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); + } +} + +void gsm_enc_Coefficients_27_39 ( + word * LARpp_j_1, + word * LARpp_j, + word * LARp) +{ + int i; + longword ltmp; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); + } +} + + +void gsm_enc_Coefficients_40_159 ( + word * LARpp_j, + word * LARp) +{ + int i; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARp++, LARpp_j++) { + *LARp = *LARpp_j; + } +} + +/* 4.2.9.2 */ + +void gsm_enc_LARp_to_rp ( + word * LARp) /* [0..7] IN/OUT */ +/* + * The input of this procedure is the interpolated LARp[0..7] array. + * The reflection coefficients, rp[i], are used in the analysis + * filter and in the synthesis filter. + */ +{ + int i; + word temp; + longword ltmp; + + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, LARp++) { + + /* temp = GSM_ABS( *LARp ); + * + * if (temp < 11059) temp <<= 1; + * else if (temp < 20070) temp += 11059; + * else temp = GSM_ADD( temp >> 2, 26112 ); + * + * *LARp = *LARp < 0 ? -temp : temp; + */ + + if (*LARp < 0) { + temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); + *LARp = - ((temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 ))); + } else { + temp = *LARp; + *LARp = (temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 )); + } + } +} + + +/* 4.2.10 */ +void gsm_enc_Short_term_analysis_filtering ( + struct gsm_state * S, + word * rp, /* [0..7] IN */ + int k_n, /* k_end - k_start */ + word * s /* [0..n-1] IN/OUT */ +) +/* + * This procedure computes the short term residual signal d[..] to be fed + * to the RPE-LTP loop from the s[..] signal and from the local rp[..] + * array (quantized reflection coefficients). As the call of this + * procedure can be done in many ways (see the interpolation of the LAR + * coefficient), it is assumed that the computation begins with index + * k_start (for arrays d[..] and s[..]) and stops with index k_end + * (k_start and k_end are defined in 4.2.9.1). This procedure also + * needs to keep the array u[0..7] in memory for each call. + */ +{ + word * u = S->u; + int i; + word di, zzz, ui, sav, rpi; + longword ltmp; + int j; + + _Pragma("loopbound min 13 max 120") + for (j=0; jLARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; + + word LARp[8]; + +#undef FILTER +# define FILTER gsm_enc_Short_term_analysis_filtering + + gsm_enc_Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); + + gsm_enc_Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s); + + gsm_enc_Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 14, s + 13); + + gsm_enc_Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s + 27); + + gsm_enc_Coefficients_40_159( LARpp_j, LARp); + gsm_enc_LARp_to_rp( LARp ); + FILTER( S, LARp, 120, s + 40); +} + +/* lpc.c */ +#undef P + +/* + * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION + */ + +/* 4.2.4 */ + + +void gsm_enc_Autocorrelation ( + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +/* + * The goal is to compute the array L_ACF[k]. The signal s[i] must + * be scaled in order to avoid an overflow situation. + */ +{ + int k, i; + + word temp, smax, scalauto; + + /* Dynamic scaling of the array s[0..159] + */ + + /* Search for the maximum. + */ + smax = 0; + + _Pragma("loopbound min 160 max 160") + for (k = 0; k <= 159; k++) { + temp = GSM_ABS( s[k] ); + if (temp > smax) smax = temp; + } + + /* Computation of the scaling factor. + */ + if (smax == 0) scalauto = 0; + else { + scalauto = 4 - gsm_enc_norm( (longword)smax << 16 );/* sub(4,..) */ + } + + /* Scaling of the array s[0...159] + */ + + if (scalauto > 0) { + +# define SCALE(n) \ + case n: \ + _Pragma("loopbound min 160 max 160") \ + for (k = 0; k <= 159; k++) \ + s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ + break; + + switch (scalauto) { + SCALE(1) + SCALE(2) + SCALE(3) + SCALE(4) + } +# undef SCALE + } + + /* Compute the L_ACF[..]. + */ + { + word * sp = s; + word sl = *sp; +#undef STEP +# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); + +# define NEXTI sl = *++sp + + + _Pragma("loopbound min 9 max 9") + for (k = 9; k--; L_ACF[k] = 0) ; + + STEP (0); + NEXTI; + STEP(0); STEP(1); + NEXTI; + STEP(0); STEP(1); STEP(2); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); + + _Pragma("loopbound min 152 max 152") + for (i = 8; i <= 159; i++) { + + NEXTI; + + STEP(0); + STEP(1); STEP(2); STEP(3); STEP(4); + STEP(5); STEP(6); STEP(7); STEP(8); + } + + _Pragma("loopbound min 9 max 9") + for (k = 9; k--; L_ACF[k] <<= 1) ; + + } + /* Rescaling of the array s[0..159] + */ + if (scalauto > 0) { + _Pragma("loopbound min 160 max 160") + for (k = 160; k--; *s++ <<= scalauto) ; + } +} + +/* 4.2.5 */ + +void gsm_enc_Reflection_coefficients ( + longword * L_ACF, /* 0...8 IN */ + word * r /* 0...7 OUT */ +) +{ + int i, m, n; + word temp; + longword ltmp; + word ACF[9]; /* 0..8 */ + word P[ 9]; /* 0..8 */ + word K[ 9]; /* 2..8 */ + + /* Schur recursion with 16 bits arithmetic. + */ + + if (L_ACF[0] == 0) { + _Pragma("loopbound min 8 max 8") + for (i = 8; i--; *r++ = 0) ; + return; + } + + temp = gsm_enc_norm( L_ACF[0] ); + + /* ? overflow ? */ + _Pragma("loopbound min 9 max 9") + for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); + + /* Initialize array P[..] and K[..] for the recursion. + */ + + _Pragma("loopbound min 7 max 7") + for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; + + _Pragma("loopbound min 9 max 9") + for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; + + /* Compute reflection coefficients + */ + _Pragma("loopbound min 8 max 8") + for (n = 1; n <= 8; n++, r++) { + + temp = P[1]; + temp = GSM_ABS(temp); + if (P[0] < temp) { + _Pragma("loopbound min 8 max 8") + for (i = n; i <= 8; i++) *r++ = 0; + return; + } + + *r = gsm_enc_div( temp, P[0] ); + + if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ + if (n == 8) return; + + /* Schur recursion + */ + temp = GSM_MULT_R( P[1], *r ); + P[0] = GSM_ADD( P[0], temp ); + + _Pragma("loopbound min 1 max 7") + for (m = 1; m <= 8 - n; ++m) { + temp = GSM_MULT_R( K[ m ], *r ); + P[m] = GSM_ADD( P[ m+1 ], temp ); + + temp = GSM_MULT_R( P[ m+1 ], *r ); + K[m] = GSM_ADD( K[ m ], temp ); + } + } +} + +/* 4.2.6 */ + +void gsm_enc_Transformation_to_Log_Area_Ratios ( + word * r /* 0..7 IN/OUT */ +) +/* + * The following scaling for r[..] and LAR[..] has been used: + * + * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. + * LAR[..] = integer( real_LAR[..] * 16384 ); + * with -1.625 <= real_LAR <= 1.625 + */ +{ + word temp; + int i; + + + /* Computation of the LAR[0..7] from the r[0..7] + */ + _Pragma("loopbound min 8 max 8") + for (i = 1; i <= 8; i++, r++) { + + temp = *r; + temp = GSM_ABS(temp); + + if (temp < 22118) { + temp >>= 1; + } else if (temp < 31130) { + temp -= 11059; + } else { + temp -= 26112; + temp <<= 2; + } + + *r = *r < 0 ? -temp : temp; + } +} + +/* 4.2.7 */ + +void gsm_enc_Quantization_and_coding ( + word * LAR /* [0..7] IN/OUT */ +) +{ + word temp; + longword ltmp; + + + /* This procedure needs four tables; the following equations + * give the optimum scaling for the constants: + * + * A[0..7] = integer( real_A[0..7] * 1024 ) + * B[0..7] = integer( real_B[0..7] * 512 ) + * MAC[0..7] = maximum of the LARc[0..7] + * MIC[0..7] = minimum of the LARc[0..7] + */ + +# undef STEP +# define STEP( A, B, MAC, MIC ) \ + temp = GSM_MULT( A, *LAR ); \ + temp = GSM_ADD( temp, B ); \ + temp = GSM_ADD( temp, 256 ); \ + temp = SASR( temp, 9 ); \ + *LAR = temp>MAC ? MAC - MIC : (tempz1; + longword L_z2 = S->L_z2; + word mp = S->mp; + + word s1; + longword L_s2; + + longword L_temp; + + word msp, lsp; + word SO; + + longword ltmp; /* for ADD */ + ulongword utmp; /* for L_ADD */ + + int k = 160; + + _Pragma("loopbound min 160 max 160") + while (k--) { + + /* 4.2.1 Downscaling of the input signal + */ + SO = SASR( *s, 3 ) << 2; + s++; + + /* 4.2.2 Offset compensation + * + * This part implements a high-pass filter and requires extended + * arithmetic precision for the recursive part of this filter. + * The input of this procedure is the array so[0...159] and the + * output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part + */ + + s1 = SO - z1; /* s1 = gsm_enc_sub( *so, z1 ); */ + z1 = SO; + + /* Compute the recursive part + */ + L_s2 = s1; + L_s2 <<= 15; + + /* Execution of a 31 bv 16 bits multiplication + */ + + msp = SASR( L_z2, 15 ); + lsp = L_z2-((longword)msp<<15); /* gsm_enc_L_sub(L_z2,(msp<<15)); */ + + L_s2 += GSM_MULT_R( lsp, 32735 ); + L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ + L_z2 = GSM_L_ADD( L_temp, L_s2 ); + + /* Compute sof[k] with rounding + */ + L_temp = GSM_L_ADD( L_z2, 16384 ); + + /* 4.2.3 Preemphasis + */ + + msp = GSM_MULT_R( mp, -28180 ); + mp = SASR( L_temp, 15 ); + *so++ = GSM_ADD( mp, msp ); + } + + S->z1 = z1; + S->L_z2 = L_z2; + S->mp = mp; +} + +/* gsm_enc_bench.c */ + +word gsm_enc_norm (longword a ) +/* + * the number of left shifts needed to normalize the 32 bit + * variable L_var1 for positive values on the interval + * + * with minimum of + * minimum of 1073741824 (01000000000000000000000000000000) and + * maximum of 2147483647 (01111111111111111111111111111111) + * + * + * and for negative values on the interval with + * minimum of -2147483648 (-10000000000000000000000000000000) and + * maximum of -1073741824 ( -1000000000000000000000000000000). + * + * in order to normalize the result, the following + * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); + * + * (That's 'ffs', only from the left, not the right..) + */ +{ + if (a < 0) { + if (a <= -1073741824) return 0; + a = ~a; + } + + return a & 0xffff0000 + ? ( a & 0xff000000 + ? -1 + gsm_enc_bitoff[ 0xFF & (a >> 24) ] + : 7 + gsm_enc_bitoff[ 0xFF & (a >> 16) ] ) + : ( a & 0xff00 + ? 15 + gsm_enc_bitoff[ 0xFF & (a >> 8) ] + : 23 + gsm_enc_bitoff[ 0xFF & a ] ); +} + +word gsm_enc_asl (word a, int n) +{ + if (n >= 16) return 0; + if (n <= -16) return -(a < 0); + if (n < 0) return gsm_enc_asr(a, -n); + return a << n; +} + +word gsm_enc_asr (word a, int n) +{ + if (n >= 16) return -(a < 0); + if (n <= -16) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(word)( -(uword)a >> n ); +# endif +} + +/* + * (From p. 46, end of section 4.2.5) + * + * NOTE: The following lines gives [sic] one correct implementation + * of the div(num, denum) arithmetic operation. Compute div + * which is the integer division of num by denum: with denum + * >= num > 0 + */ + +word gsm_enc_div ( word num, word denum) +{ + longword L_num = num; + longword L_denum = denum; + word div = 0; + int k = 15; + + /* The parameter num sometimes becomes zero. + * Although this is explicitly guarded against in 4.2.5, + * we assume that the result should then be zero as well. + */ + + if (num == 0) + return 0; + + _Pragma("loopbound min 15 max 15") + while (k--) { + div <<= 1; + L_num <<= 1; + + if (L_num >= L_denum) { + L_num -= L_denum; + div++; + } + } + + return div; +} + + + +gsm gsm_enc_create( void ) +{ + unsigned int i; + gsm r; + + r = &gsm_enc_state; + + _Pragma("loopbound min 648 max 648") + for(i=0; i < sizeof(*r); i++) + ((char *)r)[i]=0; + + r->nrp = 40; + + return r; +} + +void gsm_enc_init( void ) +{ + gsm_enc_state_ptr = gsm_enc_create(); +} + +int gsm_enc_return( void ) +{ + return gsm_enc_result; +} + +void gsm_enc_main( void ) +{ + gsm r; + unsigned i; + gsm_enc_result = 0; + + r = gsm_enc_state_ptr; + + _Pragma("loopbound min 20 max 20") + for (i=0; i < SAMPLES; i++) { + gsm_enc_encode(r, gsm_enc_pcmdata + i * 160, gsm_enc_gsmdata + i * sizeof(gsm_frame)); + } +} + +int main( int argc, char** argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete> (by)) + +/* Table 4.3a Decision level of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_enc_DLB[4] = { 6554, 16384, 26214, 32767 }; + + +/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_enc_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; + + +/* Table 4.6 Normalized direct mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_enc_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; +#endif /* PRIVATE_H */ diff --git a/baseline/source/h264_dec/changeLog.txt b/baseline/source/h264_dec/changeLog.txt new file mode 100644 index 0000000..2d5d97f --- /dev/null +++ b/baseline/source/h264_dec/changeLog.txt @@ -0,0 +1,41 @@ +File: h264dec_ldecode_macroblock.c +Original provenience: + +2015-12-21: +- Filename changed to h264dec.c +- global.h renamed to h264dec.h +- Removed commented out includes +- Removed all obsolete typedefs, enums and structs. Only remaining ones are + struct img_par and + enum SliceType +- Renamed function decode_one_macroblock to h264dec_decode_one_macroblock +- Function h264dec_decode_one_macroblock changed to void (i.e., removed statement return 0;) +- Added functions h264dec_init, h264dec_return and main +- Added forward declarations of all functions before the declarations of global + variables +- Struct 'ImageParameters' renamed to 'h264dec_ImageParameters' +- Re-ordered functions to fit template-order +- Applied code formatting according to the following rules + (incomplete, to be discussed; I basically used astyle with the attached + options file): + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: st_) followed by lowercase letter (e.g., st_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur +- Added general TACLeBench header to beginning of source code \ No newline at end of file diff --git a/baseline/source/h264_dec/copyright.txt b/baseline/source/h264_dec/copyright.txt new file mode 100644 index 0000000..fe3eece --- /dev/null +++ b/baseline/source/h264_dec/copyright.txt @@ -0,0 +1,32 @@ +/* +*********************************************************************** +* COPYRIGHT AND WARRANTY INFORMATION +* +* Copyright 2001, International Telecommunications Union, Geneva +* +* DISCLAIMER OF WARRANTY +* +* These software programs are available to the user without any +* license fee or royalty on an "as is" basis. The ITU disclaims +* any and all warranties, whether express, implied, or +* statutory, including any implied warranties of merchantability +* or of fitness for a particular purpose. In no event shall the +* contributor or the ITU be liable for any incidental, punitive, or +* consequential damages of any kind whatsoever arising from the +* use of these programs. +* +* This disclaimer of warranty extends to the user of these programs +* and user's customers, employees, agents, transferees, successors, +* and assigns. +* +* The ITU does not represent or warrant that the programs furnished +* hereunder are free of infringement of any third-party patents. +* Commercial implementations of ITU-T Recommendations, including +* shareware, may be subject to royalty fees to patent holders. +* Information regarding the ITU-T patent policy is available from +* the ITU Web site at http://www.itu.int. +* +* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY. +************************************************************************ +*/ + diff --git a/baseline/source/h264_dec/h264_dec.c b/baseline/source/h264_dec/h264_dec.c new file mode 100644 index 0000000..76af705 --- /dev/null +++ b/baseline/source/h264_dec/h264_dec.c @@ -0,0 +1,610 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: h264_dec_ldecode_macroblock.c + + Author: Inge Lille-Langoy et al. + + Function: H.264 decoder + + Source: MediaBench II + http://euler.slu.edu/~fritts/mediabench (mirror) + + Original name: h264_dec_ldecode_macroblock.c + + Changes: no functional changes + + License: see copyright.txt + +*/ + + +/* + Include section +*/ + +#include "../extra.h" +#include "h264_dec.h" + + +/* + Forward declaration of functions +*/ + +void h264_dec_init (); +int h264_dec_return (); +void h264_dec_decode_one_macroblock( struct h264_dec_img_par *img ); +void h264_dec_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +extern signed char h264_dec_mv_array[65][65][2]; +extern short h264_dec_list_imgUV[2][45][45]; +extern int h264_dec_img_m7[16][16]; + +char h264_dec_img_mpr[7][7]; +char h264_dec_dec_picture_imgUV[2][64][54]; +struct h264_dec_img_par h264_dec_img; + + +/* + Initialization- and return-value-related functions +*/ + +int h264_dec_return () +{ + return ( h264_dec_img_mpr[0][0] + h264_dec_dec_picture_imgUV[0][0][0] + 128 != + 0 ); +} + +void h264_dec_init () +{ + unsigned int i; + unsigned char *p; + volatile char bitmask = 0; + + /* + Apply volatile XOR-bitmask to entire input array. + */ + p = ( unsigned char * ) &h264_dec_mv_array[ 0 ]; + _Pragma( "loopbound min 33800 max 33800" ) + for ( i = 0; i < sizeof( h264_dec_mv_array ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &h264_dec_list_imgUV[ 0 ]; + _Pragma( "loopbound min 16200 max 16200" ) + for ( i = 0; i < sizeof( h264_dec_list_imgUV ); ++i, ++p ) + *p ^= bitmask; + + p = ( unsigned char * ) &h264_dec_img_m7[ 0 ]; + _Pragma( "loopbound min 1024 max 1024" ) + for ( i = 0; i < sizeof( h264_dec_img_m7 ); ++i, ++p ) + *p ^= bitmask; + + h264_dec_img.mb_cr_size_x = 8; + h264_dec_img.mb_cr_size_y = 8; + h264_dec_img.num_blk8x8_uv = 2; + h264_dec_img.pix_c_x = 256; + h264_dec_img.pix_c_y = 256; + h264_dec_img.width_cr = 352; + h264_dec_img.apply_weights = 0; + h264_dec_img.direct_spatial_mv_pred_flag = 1; + h264_dec_img.type = 1; + h264_dec_img.wp_round_chroma = 0; + h264_dec_img.chroma_log2_weight_denom = 0; +} + + +/* + Algorithm core functions +*/ + +void h264_dec_decode_one_macroblock( struct h264_dec_img_par *img ) +{ + int i = 0, j = 0, ii = 0, jj = 0, i1 = 0, j1 = 0, j4 = 0, i4 = 0; + int uv; + int ioff, joff; + int bw_pred = 0, fw_pred = 0, ifx; + int ii0, jj0, ii1, jj1, if1, jf1, if0, jf0; + int f1_x, f1_y, f2_x, f2_y, f3, f4; + + short fw_refframe = -1, bw_refframe = -1; + int mv_mode, pred_dir, intra_prediction; // = currMB->ref_frame; + short fw_ref_idx = -1, bw_ref_idx = -1; + + int mb_nr = 0; + short dec_picture_ref_idx = 0; + + short active_sps_chroma_format_idc = 1; + short active_pps_weighted_pred_flag = 0; + short active_pps_weighted_bipred_idc = 0; + + int smb = 0; + int max_y_cr = 287; + + int jf; + + int direct_pdir = -1; + + int curr_mb_field = 0; + + int b8, b4; + + int residue_transform_flag = 0; + + if ( 1 ) { + f1_x = 64 / img->mb_cr_size_x; + f2_x = f1_x - 1; + + f1_y = 64 / img->mb_cr_size_y; + f2_y = f1_y - 1; + + f3 = f1_x * f1_y; + f4 = f3 >> 1; + + _Pragma( "loopbound min 2 max 2" ) + for ( uv = 0; uv < 2; uv++ ) { + intra_prediction = 0; + + + _Pragma( "loopbound min 1 max 1" ) + for ( b8 = 0; b8 < ( img->num_blk8x8_uv / 2 ); b8++ ) { + _Pragma( "loopbound min 4 max 4" ) + for ( b4 = 0; b4 < 4; b4++ ) { + joff = 0; + j4 = img->pix_c_y + joff; + ioff = 0; + i4 = img->pix_c_x + ioff; + + mv_mode = 1; + pred_dir = -1; + + if ( !intra_prediction ) { + if ( pred_dir != 2 ) { + + _Pragma( "loopbound min 4 max 4" ) + for ( jj = 0; jj < 4; jj++ ) { + jf = ( ( j4 + jj ) / ( img->mb_cr_size_y / 4 ) ) % 64; + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) { + ifx = ( ( i4 + ii ) / ( img->mb_cr_size_x / 4 ) ) % 64; + i1 = ( i4 + ii ) * f1_x + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) + j1 = ( j4 + jj ) * f1_y + h264_dec_mv_array[jf][ifx][1]; + else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y / 2 ) + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + ++mb_nr; + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( + ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : ( i1 + f2_x ) / f1_x ) ) + ? ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) + ? max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) ) % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + if ( img->apply_weights ) { + } else { + h264_dec_img_mpr[ii + ioff][jj + joff] + = ( if0 * jf0 * h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + } + } + } else { + + _Pragma( "loopbound min 4 max 4" ) + for ( jj = 0; jj < 4; jj++ ) { + jf = ( j4 + jj ) / ( img->mb_cr_size_y / 4 ); + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) { + ifx = ( i4 + ii ) / ( img->mb_cr_size_x / 4 ); + direct_pdir = 2; + + if ( mv_mode == 0 && img->direct_spatial_mv_pred_flag ) { + if ( dec_picture_ref_idx != -1 ) { + fw_refframe = 0; + fw_ref_idx = fw_refframe; + } + if ( dec_picture_ref_idx != -1 ) { + bw_refframe = 0; + bw_ref_idx = bw_refframe; + } + + if ( dec_picture_ref_idx == -1 ) direct_pdir = 0; + else + if ( dec_picture_ref_idx == -1 ) direct_pdir = 1; + + if ( direct_pdir == 0 || direct_pdir == 2 ) { + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * + f1_y + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) + / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( + ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( + ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? ( ( + j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) + ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) + ) % 45; + + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + fw_pred = ( if0 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + if ( direct_pdir == 1 || direct_pdir == 2 ) { + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) + ? img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) ) + % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + bw_pred = ( if0 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * + h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * + h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + + } else { + fw_refframe = 0; + bw_refframe = 0; + + fw_ref_idx = fw_refframe; + bw_ref_idx = bw_refframe; + + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) + % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : + ( j1 + f2_y ) / f1_y ) : 0 ) ) % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + fw_pred = ( if0 * jf0 * h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + + i1 = ( img->pix_c_x + ii + ioff ) * f1_x + + h264_dec_mv_array[jf][ifx][0]; + + if ( !curr_mb_field ) { + j1 = ( img->pix_c_y + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + if ( mb_nr % 2 == 0 ) { + j1 = ( ( img->pix_c_y ) / 2 + jj + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } else { + j1 = ( ( img->pix_c_y - img->mb_cr_size_y ) / 2 + jj + + joff ) * f1_y + + h264_dec_mv_array[jf][ifx][1]; + } + } + + if ( active_sps_chroma_format_idc == 1 ) + j1 += 0; + + ii0 = ( ( ( 0 < ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) ) ? + ( ( i1 / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : i1 / f1_x ) : 0 ) ) % 45; + jj0 = ( ( ( 0 < ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) ) ? + ( ( j1 / f1_y > max_y_cr ) ? + max_y_cr : j1 / f1_y ) : 0 ) ) % 45; + ii1 = ( ( ( 0 < ( ( ( i1 + f2_x ) / + f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) ) ? + ( ( ( i1 + f2_x ) / f1_x > img->width_cr - 1 ) ? + img->width_cr - 1 : + ( i1 + f2_x ) / f1_x ) : 0 ) ) % 45; + jj1 = ( ( ( 0 < ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) ) ? + ( ( ( j1 + f2_y ) / f1_y > max_y_cr ) ? + max_y_cr : ( j1 + f2_y ) / f1_y ) : 0 ) ) % 45; + + if1 = ( i1 & f2_x ); + jf1 = ( j1 & f2_y ); + if0 = f1_x - if1; + jf0 = f1_y - jf1; + + bw_pred = ( if0 * jf0 * h264_dec_list_imgUV[uv][jj0][ii0] + + if1 * jf0 * h264_dec_list_imgUV[uv][jj0][ii1] + + if0 * jf1 * h264_dec_list_imgUV[uv][jj1][ii0] + + if1 * jf1 * h264_dec_list_imgUV[uv][jj1][ii1] + + f4 ) / f3; + } + + if ( img->apply_weights ) { + if ( ( ( active_pps_weighted_pred_flag && + ( img->type == P_SLICE || img->type == SP_SLICE ) ) + || ( active_pps_weighted_bipred_idc == 1 && + ( img->type == B_SLICE ) ) ) + && curr_mb_field ) { + fw_ref_idx >>= 1; + bw_ref_idx >>= 1; + } + + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 1 ) { + img->mpr[ii + ioff][jj + joff] = + ( ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) < 0 ? 0 : + ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) ) + 0; + } else + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 0 ) { + img->mpr[ii + ioff][jj + joff] = + ( ( ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) ) < 0 ? + 0 : + ( ( ( img->wp_round_chroma ) >> + img->chroma_log2_weight_denom ) ) ) ; + } else { + + int alpha_fw = 0; + int alpha_bw = 0; + + img->mpr[ii + ioff][jj + joff] = + ( ( ( alpha_fw * fw_pred + alpha_bw * + bw_pred + + ( 1 << img->chroma_log2_weight_denom ) ) >> ( + img->chroma_log2_weight_denom + 1 ) ) < 0 ? + 0 : ( ( alpha_fw * fw_pred + alpha_bw * + bw_pred + + ( 1 << img->chroma_log2_weight_denom ) ) >> + ( img->chroma_log2_weight_denom + 1 ) ) ); + } + } else { + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 1 ) + img->mpr[ii + ioff][jj + joff] = bw_pred; + else + if ( img->direct_spatial_mv_pred_flag + && direct_pdir == 0 ) + img->mpr[ii + ioff][jj + joff] = fw_pred; + else { + img->mpr[ii + ioff][jj + joff] = ( fw_pred + bw_pred + + + 1 ) / 2; + } + } + } + } + } + } + + if ( !smb ) { + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) { + jj = 0; + _Pragma( "loopbound min 4 max 4" ) + for ( ; jj < 4; jj++ ) { + if ( !residue_transform_flag ) { + h264_dec_dec_picture_imgUV[uv][( j4 + jj ) % 64] + [( i4 + ii ) % 54] + = h264_dec_img_m7[ii][jj]; + } + } + } + } + } + } + + if ( smb ) { + _Pragma( "loopbound min 2 max 2" ) + for ( j = 4; j < 6; j++ ) { + joff = ( j - 4 ) * 4; + j4 = img->pix_c_y + joff; + _Pragma( "loopbound min 2 max 2" ) + for ( i = 0; i < 2; i++ ) { + ioff = i * 4; + i4 = img->pix_c_x + ioff; + + _Pragma( "loopbound min 4 max 4" ) + for ( ii = 0; ii < 4; ii++ ) + _Pragma( "loopbound min 4 max 4" ) + for ( jj = 0; jj < 4; jj++ ) { + h264_dec_dec_picture_imgUV[uv][( j4 + jj ) % 64] + [( i4 + ii ) % 54] + = h264_dec_img_m7[ii][jj]; + } + } + } + } + } + } +} + + +/* + Main functions +*/ + +void _Pragma( "entrypoint" ) h264_dec_main( void ) +{ + h264_dec_decode_one_macroblock( &h264_dec_img ); +} + + +int main( int argc, char** argv ) +{ + SET_UP + for (jobsComplete=-1; jobsCompletesource_memory_end) +#define read_byte() (*(source_ptr++)) + +If you want to compress *to* memory, before entering in a xxxcoding procedure +('xxx' is the actual extension to replace with a given codec), you have to add +a pointer. Note that the pointer 'dest_memory_base' is not to add, it is just +given there to specify the address of the destination memory zone you are +going to encode or decode. + +unsigned char *dest_memory_base, /* Base of the destination memory */ + *dest_ptr; /* Used in the xxxcoding procedure */ +void pre_start() +{ dest_ptr=dest_memory_base; + xxxcoding(); +} + +Of course, you can combine both from and to memory in the pre_start() procedure. +The files dest_file and source_file handled in the main() function are +to remove... + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + xxxcoding(); +} + +In fact, to write to memory, the problem is in the write_byte(x) procedure. +This problem exists because your destination zone can either be a static +zone or a dynamically allocated zone. In the two cases, you have to check +if there is no overflow, especially if the coder is not efficient and must +produce more bytes than you reserved in memory. + +In the first case, with a *static* zone, write_byte(x) macro should look like +that: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + exit(1); \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +In the static version, the pre_start() procedure is to modify as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=...; /* Set up to the actual destination zone length */ + current_size=0; /* Number of written bytes */ + xxxcoding(); +} +Otherwise, dest_ptr is a zone created by the malloc instruction and you can try +to resize the allocated zone with the realloc instruction. Note that I increment +the zone one kilo-bytes by one kylo-bytes. You have to add two other variables: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + { dest_zone_length += 1024; \ + if ((dest_ptr=(unsigned char *)realloc(dest_ptr,dest_zone_length*sizeof(unsigned char)))==NULL) \ + exit(1); /* You can't compress in memory \ + => I exit but *you* can make a routine to swap on disk */ \ + } \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +With the dynamically allocated version, change the pre_start() routine as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=1024; + if ((dest_ptr=(unsigned char *)malloc(dest_zone_length*sizeof(unsigned char)))==NULL) + exit(1); /* You need at least 1 kb in the dynamical memory ! */ + current_size=0; /* Number of written bytes */ + xxxcoding(); + /* Handle the bytes in dest_ptr but don't forget to free these bytes with: + free(dest_ptr); + */ +} + +The previously given macros work as: + +void demo() /* The file opening, closing and variables + must be set up by the calling procedure */ +{ unsigned char byte; + /* And not 'char byte' (!) */ + while (!end_of_data()) + { byte=read_byte(); + printf("Byte read=%c\n",byte); + } +} + +You must not change the rest of the program unless you're really sure and +really need to do it! + ++==========================================================+ +| The RLE encoding | ++==========================================================+ + +RLE is an acronym that stands for Run Length Encoding. You may encounter it +as an other acronym: RLC, Run Length Coding. + +The idea in this scheme is to recode your data with regard to the repetition +frames. A frame is one or more bytes that occurr one or several times. + +There are several means to encode occurrences. So, you'll have several codecs. +For example, you may have a sequence such as: +0,0,0,0,0,0,255,255,255,2,3,4,2,3,4,5,8,11 + +Some codecs will only deal with the repetitions of '0' and '255' but some other +will deal with the repetitions of '0', '255', and '2,3,4'. + +You have to keep in your mind something important based on this example. A codec +won't work on all the data you will try to compress. So, in case of non +existence of sequence repetitions, the codecs based on RLE schemes must not +display a message to say: "Bye bye". Actually, they will try to encode these +non repeted data with a value that says "Sorry, I only make a copy of the inital +input". Of course, a copy of the input data with an header in front of this copy +will make a biggest output data but if you consider the whole data to compress, +the encoding of repeated frames will take less space than the encoding +of non-repeated frames. + +All of the algorithms with the name of RLE have the following look with three +or four values: +- Value saying if there's a repetition +- Value saying how many repetitions (or non repetition) +- Value of the length of the frame (useless if you just encode frame +with one byte as maximum length) +- Value of the frame to repeat (or not) + +I gave four algorithms to explain what I say. + +*** First RLE scheme *** + +The first scheme is the simpliest I know, and looks like the one used in MAC +system (MacPackBit) and some image file formats such as Targa, PCX, TIFF, ... + +Here, all compressed blocks begin with a byte, named header, which description +is: + +Bits 7 6 5 4 3 2 1 0 +Header X X X X X X X X + +Bits 7: Compression status (1=Compression applied) + 0 to 6: Number of bytes to handle + +So, if the bit 7 is set up to 0, the 0 to 6 bits give the number of bytes +that follow (minus 1, to gain more over compress) and that were not compressed +(native bytes). If the bit 7 is set up to 1, the same 0 to 6 bits give +the number of repetition (minus 2) of the following byte. + +As you see, this method only handle frame with one byte. + +Additional note: You have 'minus 1' for non-repeated frames because you must +have at least one byte to compress and 'minus 2' for repeated frames because the +repetition must be 2, at least. + +Compression scheme: + + First byte=Next + /\ + / \ +Count the byte Count the occurrence of NON identical +occurrences bytes (maximum 128 times) +(maximum 129 times) and store them in an array + | | + | | + 1 bit '1' 1 bit '0' ++ 7 bits giving + 7 bits giving + the number (-2) the number (-1) + of repetitions of non repetition ++ repeated byte + n non repeated bytes + | | + 1xxxxxxx,yyyyyyyy 0xxxxxxx,n bytes +[-----------------] [----------------] + +Example: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 1,255,15, | -1 + 255,255, | 128,255, | 0 + 15,15, | 128,15, | 0 + 255,255,255, | 129,255, | +1 + 15,15,15, | 129,15, | +1 + 255,255,255,255, | 130,255, | +2 + 15,15,15,15 | 130,15 | +2 + +See codecs source codes: codrle1.c and dcodrle1.c + +*** Second RLE scheme *** + +In the second scheme of RLE compression you look for the less frequent byte +in the source to compress and use it as an header for all compressed block. + +In the best cases, the occurrence of this byte is zero in the data to compress. + +Two possible schemes, firstly with handling frames with only one byte, +secondly with handling frames with one byte *and* more. The first case is +the subject of this current compression scheme, the second is the subject +of next compression scheme. + +For the frame of one byte, header byte is written in front of all repetition +with at least 4 bytes. It is then followed by the repetition number minus 1 and +the repeated byte. +Header byte, Occurrence number-1, repeated byte + +If a byte don't repeat more than tree times, the three bytes are written without +changes in the destination stream (no header nor length, nor repetition in front +or after theses bytes). + +An exception: If the header byte appears in the source one, two, three and up +times, it'll be respectively encoded as following: +- Header byte, 0 +- Header byte, 1 +- Header byte, 2 +- Header byte, Occurrence number-1, Header byte + +Example, let's take the previous example. A non frequent byte is zero-ASCII +because it never appears. + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 255,15, | -1 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 0,3,255, | -1 + 15,15,15,15 | 0,3,15 | -1 + +If the header would appear, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 0, | 0,0, | +1 + 255, | 255, | 0 + 0,0, | 0,1, | 0 + 15, | 15, | 0 + 0,0,0, | 0,2, | -1 + 255, | 255, | 0 + 0,0,0,0 | 0,3,0 | -1 + +See codecs source codes: codrle2.c and dcodrle2.c + +*** Third RLE scheme *** + +It's the same idea as the second scheme but we can encode frames with +more than one byte. So we have three cases: + +- If it was the header byte, whatever is its occurrence, you encode it with: +Header byte,0,number of occurrence-1 +- For frames which (repetition-1)*length>3, encode it as: +Header byte, Number of frame repetition-1, frame length-1,bytes of frame +- If no previous cases were detected, you write them as originally (no header, +nor length, nor repetition in front or after theses bytes). + +Example based on the previous examples: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +----------------------------------------------------------------------------- + 255,15, | 255,15, | 0 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 255,255,255,255, | 0 + 15,15,15,15, | 15,15,15,15, | 0 + 16,17,18,16,17,18, |16,17,18,16,17,18,| 0 + 255,255,255,255,255, | 0,4,0,255, | -1 + 15,15,15,15,15, | 0,4,0,15, | -1 + 16,17,18,16,17,18,16,17,18,| 0,2,2,16,17,18, | -3 + 16,17,18,19,16,17,18,19 |0,1,3,16,17,18,19 | -1 + +If the header (value 0) would be met, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 0, | 0,0,0, | +2 + 255, | 255, | 0 + 0,0, | 0,0,1, | +1 + 15, | 15, | 0 + 0,0,0, | 0,0,2, | 0 + 255, | 255, | 0 + 0,0,0,0 | 0,0,3 | -1 + +See codecs source codes: codrle3.c and dcodrle3.c + +*** Fourth RLE scheme *** + +This last RLE algorithm better handles repetitions of any kind (one byte +and more) and non repetitions, including few non repetitions, and does not +read the source by twice as RLE type 3. + +Compression scheme is: + + First byte=Next byte? + /\ + Yes / \ No + / \ + 1 bit '0' 1 bit '1' + / \ + / \ + Count the Motif of several + occurrences repeated byte? + of 1 repeated ( 65 bytes repeated + byte (maximum 257 times maxi) + 16449 times) /\ + /\ / \ + / \ / \ + / \ / \ + / \ / \ + 1 bit '0' 1 bit '1' 1 bit '0' 1 bit '1' ++ 6 bits + 14 bits + 6 bits of | +giving the giving the the length Number of non repetition +length (-2) length (-66) of the motif (maximum 8224) +of the of the + 8 bits of /\ +repeated byte repeated byte the number (-2) < 33 / \ > 32 ++ repeated byte + repeated byte of repetition / \ + | | + bytes of the 1 bit '0' 1 bit '1' + | | motif + 5 bits of + 13 bits + | | | the numer (-1) of the + | | | of non number (-33) + | | | repetition of repetition + | | | + non + non + | | | repeated repeated + | | | bytes bytes + | | | | | + | | | | 111xxxxx,xxxxxxxx,n bytes + | | | | [-------------------------] + | | | | + | | | 110xxxxx,n bytes + | | | [----------------] + | | | + | | 10xxxxxx,yyyyyyyy,n bytes + | | [-------------------------] + | | + | 01xxxxxx,xxxxxxxx,1 byte + | [------------------------] + | + 00xxxxxx,1 byte +[---------------] + +Example, same as previously: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 255,15 | 11000001b,255,15, | +1 + 255,255 | 00000000b,255, | 0 + 15,15 | 00000000b,15, | 0 + 255,255,255 | 00000001b,255, | -1 + 15,15,15 | 00000001b,15, | -1 + 255,255,255,255 | 00000010b,255, | -2 + 15,15,15,15 | 00000010b,15, | -2 + 16,17,18,16,17,18 |10000001b,0,16,17,18,| -1 + 255,255,255,255,255 | 00000011b,255, | -3 + 15,15,15,15,15 | 00000011b,15, | -3 + 16,17,18,16,17,18,16,17,18 | 10000001b,16,17,18, | -4 + 16,17,18,19,16,17,18,19 |10000010b,16,17,18,19| -2 + ++==========================================================+ +| The Huffman encoding | ++==========================================================+ + +This method comes from the searcher who established the algorithm in 1952. +This method allows both a dynamic and static statistic schemes. A statistic +scheme works on the data occurrences. It is not as with RLE where you had +a consideration of the current occurrence of a frame but rather a consideration +of the global occurrences of each data in the input stream. In this last case, +frames can be any kinds of sequences you want. On the other hand, Huffman +static encoding appears in some compressers such as ARJ on PCs. This enforces +the encoder to consider every statistic as the same for all the data you have. +Of course, the results are not as good as if it were a dynamic encoding. +The static encoding is faster than the dynamic encoding but the dynamic encoding +will be adapted to the statistic of the bytes of the input stream and will +of course become more efficient by producing shortest output. + +The main idea in Huffman encoding is to re-code every byte with regard to its +occurrence. The more frequent bytes in the data to compress will be encoded with +less than 8 bits and the others could need 8 bits see even more to be encoded. +You immediately see that the codes associated to the different bytes won't have +identical size. The Huffman method will actually require that the binary codes +have not a fixed size. We speak then about variable length codes. + +The dynamical Huffman scheme needs the binary trees for the encoding. This +enables you to obtain the best codes, adapted to the source data. +The demonstration won't be given there. To help the neophyt, I will just explain +what is a binary tree. + +A binary tree is special fashion to represent the data. A binary tree is +a structure with an associated value with two pointers. The term of binary has +been given because of the presence of two pointers. Because of some conventions, +one of the pointer is called left pointer and the second pointer is called right +pointer. Here is a visual representation of a binary tree. + + Value + / \ + / \ + Value Value + / \ / \ +... ... ... ... + +One problem with a binary encoding is a prefix problem. A prefix is the first +part of the representation of a value, e.g. "h" and "he" are prefixes of "hello" +but not "el". To understand the problem, let's code the letters "A", "B", "C", +"D", and "E" respectively as 00b, 01b, 10b, 11b, and 100b. When you read +the binary sequence 00100100b, you are unable to say if this comes from "ACBA" +or "AEE". To avoid such situations, the codes must have a prefix property. +And the letter "E" mustn't begin with the sequence of an other code. With "A", +"B", "C", "D", and "E" respectively affected with 1b, 01b, 001b, 0001b, and +0000b, the sequence 1001011b will only be decoded as "ACBA". + + 1 0 +<- /\ -> + / \ + "A" /\ + "B" \ + /\ + "C" \ + /\ + "D" "E" + +As you see, with this tree, an encoding will have the prefix property +if the bytes are at the end of each "branch" and you have no byte at the "node". +You also see that if you try to reach a character by the right pointer you add +a bit set to 0 and by the left pointer, you add a bit set to 1 to the current +code. The previous *bad* encoding provide the following bad tree: + + /\ + / \ + / \ + /\ /\ + / \ "B" "A" + / \ +"D" "C"\ + / \ + "E" + +You see here that the coder shouldn't put the "C" at a node... + +As you see, the largest binary code are those with the longest distance +from the top of the tree. Finally, the more frequent bytes will be the highest +in the tree in order you have the shortest encoding and the less frequent bytes +will be the lowest in the tree. + +From an algorithmic point of view, you make a list of each byte you encountered +in the stream to compress. This list will always be sorted. The zero-occurrence +bytes are removed from this list. You take the two bytes with the smallest +occurrences in the list. Whenever two bytes have the same "weight", you take two +of them regardless to their ASCII value. You join them in a node. This node will +have a fictive byte value (256 will be a good one!) and its weight will be +the sum of the two joined bytes. You replace then the two joined bytes with +the fictive byte. And you continue so until you have one byte (fictive or not) +in the list. Of course, this process will produce the shortest codes if the list +remains sorted. I will not explain with arcana hard maths why the result +is a set of the shortest bytes... + +Important: I use as convention that the right sub-trees have a weight greater +or equal to the weight of the left sub-trees. + +Example: Let's take a file to compress where we notice the following +occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +We will begin by joining the bytes 83 and 222. This will produce a fictive node +1 with a weight of 20+5=25. + +(Fictive 1,25) + /\ + / \ +(222,5) (83,20) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 1 | 25 + 77 | 24 + 115 | 21 + +Note that the list is sorted... The smallest values in the frequences are 21 and +24. That is why we will take the bytes 77 and 115 to build the fictive node 2. + +(Fictive 2,45) + /\ + / \ +(115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 2 | 45 + Fictive 1 | 25 + +The nodes with smallest weights are the fictive 1 and 2 nodes. These are joined +to build the fictive node 3 whose weight is 40+25=70. + + (Fictive 3,70) + / \ + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 3 | 70 + +The fictive node 3 is linked to the byte 31. Total weight: 280+70=350. + + (Fictive 4,350) + / \ + / \ + / \ + / \ (31,280) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 4 | 350 + 0 | 338 + 255 | 300 + +As you see, being that we sort the list, the fictive node 4 has become the first +of the list. We join the bytes 0 and 255 in a same fictive node, the number 5 +whose weight is 338+300=638. + +(Fictive 5,638) + /\ + / \ +(255,300) (0,338) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 5 | 638 + Fictive 4 | 350 + +The fictive nodes 4 and 5 are finally joined. Final weight: 638+350=998 bytes. +It is actually the total byte number in the initial file: 338+300+24+21+20+5. + + (Tree,998) + 1 / \ 0 + <- / \ -> + / \ + / \ + / \ + / \ / \ + / \ / \ + / \ / \ + / \ (31,280) (255,300) (0,338) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Bytes | Huffman codes | Frequences | Binary length*Frequence +------------------------------------------------------------ + 0 | 00b | 338 | 676 + 255 | 01b | 300 | 600 + 31 | 10b | 280 | 560 + 77 | 1101b | 24 | 96 + 115 | 1100b | 21 | 84 + 83 | 1110b | 20 | 80 + 222 | 1111b | 5 | 20 + +Results: Original file size: (338+300+280+24+21+20+5)*8=7904 bits (=998 bytes) +versus 676+600+560+96+84+80+20=2116 bits, i.e. 2116/8=265 bytes. + +Now you know how to code an input stream. The last problem is to decode all this +stuff. Actually, when you meet a binary sequence you can't say whether it comes +from such byte list or such other one. Furthermore, if you change the occurrence +of one or two bytes, you won't obtain the same resulting binary tree. Try for +example to encode the previous list but with the following occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 255 | 418 + 0 | 300 + 31 | 100 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +As you can observe it, the resulting binary tree is quite different, we had yet +the same initial bytes. To not be in such a situation we will put an header +in front of all data. I can't comment longly this header but I can say +I minimize it as much as I could. The header is divided into two parts. +The first part of this header looks closely to a boolean table (coded more or +less in binary to save space) and the second part provide to the decoder +the binary code associated to each byte encountered in the original input +stream. + +Here is a summary of the header: + +First part +---------- + First bit + / \ + 1 / \ 0 + / \ + 256 bits set to 0 or 1 5 bits for the number n (minus 1) + depending whether the of bytes encountered + corresponding byte was in the file to compres + in the file to compress | + (=> n bits set to 1, \ / + n>32) n values of 8-bits (n<=32) + \ / + \ / + \ / +Second part | +----------- | + | + +------------->| +(n+1) times | | +(n bytes of | First bit? +the values | / \ +encountered | 1 / \ 0 +in the | / \ +source file | 8 bits of 5 bits of the ++ the code | the length length (-1) +of a | (-1) of the of the following +fictive | following binary +byte | binary code code +to stop the | (length>32) (length<=32) +decoding. | \ / +The fictive | \ / +is set to | \ / +256 in the | | +Huffman | binary code +-tree of | | +encoding) +--------------| + | + Binary encoding of the source file + | + Code of end of encoding + | + + +With my codecs I can handle binary sequences with a length of 256 bits. +This correspond to encode all the input stream from one byte to infinite length. +In fact if a byte had a range from 0 to 257 instead of 0 to 255, I would have a +bug with my codecs with an input stream of at least 370,959,230,771,131,880,927, +453,318,055,001,997,489,772,178,180,790,105 bytes !!! + +Where come this explosive number? In fact, to have a severe bug, I must have +a completely unbalanced tree: + + Tree + /\ + \ + /\ + \ + /\ + \ + ... + /\ + \ + /\ + +Let's take the following example: + +Listed bytes | Frequences (Weight) +---------------------------------- + 32 | 5 + 101 | 3 + 97 | 2 + 100 | 1 + 115 | 1 + +This produces the following unbalanced tree: + + Tree + /\ +(32,5) \ + /\ + (101,3) \ + /\ + (97,2) \ + /\ + (115,1) (100,1) + +Let's speak about a mathematical series: The Fibonacci series. It is defined as +following: + +{ Fib(0)=0 +{ Fib(1)=1 +{ Fib(n)=Fib(n-2)+Fib(n-1) + +Fib(0)=0, Fib(1)=1, Fib(2)=1, Fib(3)=2, Fib(4)=3, Fib(5)=5, Fib(6)=8, Fib(7)=13, +etc. + +But 1, 1, 2, 3, 5, 8 are the occurrences of our list! We can actually +demonstrate that to have an unbalanced tree, we have to take a list with +an occurrence based on the Fibonacci series (these values are minimal). +If the data to compress have m different bytes, when the tree is unbalanced, +the longest code need m-1 bits. In our little previous example where m=5, +the longest codes are associated to the bytes 100 and 115, respectively coded +0001b and 0000b. We can also say that to have an unbalanced tree we must have +at least 5+3+2+1+1=12=Fib(7)-1. To conclude about all that, with a coder that +uses m-1 bits, you must never have an input stream size over than Fib(m+2)-1, +otherwise, there could be a bug in the output stream. Of course, with my codecs +there will never be a bug because I can deal with binary code sizes of 1 to 256 +bits. Some encoder could use that with m=31, Fib(31+2)-1=3,524,577 and m=32, +Fib(32+2)-1=5,702,886. And an encoder that uses unisgned integer of 32 bits +shouldn't have a bug until about 4 Gb... + ++==========================================================+ +| The LZW encoding | ++==========================================================+ + +The LZW scheme is due to three searchers, i.e. Abraham Lempel and Jacob Ziv +worked on it in 1977, and Terry Welch achieved this scheme in 1984. + +LZW is patented in USA. This patent, number 4,558,302, is covered by Unisys +Corporation. You can usually write (without fees) software codecs which use +the LZW scheme but hardware companies can't do so. You may get a limited +licence by writting to: +Welch Licencing Department +Office of the General Counsel +M/S C1SW19 +Unisys corporation +Blue Bell +Pennsylvania, 19424 (USA) + +If you're occidental, you are surely using an LZW encoding every time you are +speaking, especially when you use a dictionary. Let's consider, for example, +the word "Cirrus". As you read a dictionary, you begin with "A", "Aa", and so +on. But a computer has no experience and it must suppose that some words +already exist. That is why with "Cirrus", it supposes that "C", "Ci", "Cir", +"Cirr", "Cirru", and "Cirrus" exist. Of course, being that this is a computer, +all these words are encoded as index numbers. Every time you go forward, you add +a new number associated to the new word. Being that a computer is byte-based +and not alphabetic-based, you have an initial dictionary of 256 letters instead +of our 26 ('A' to 'Z') letters. + +Example: Let's code "XYXYZ". First step, "X" is recognized in the initial +dictionary of 256 letters as the 89th. Second step, "Y" is read. Does "XY" +exist? No, then "XY" is stored as the word 256. You write in the output stream +the ASCII of "X", i.e. 88. Now "YX" is tested as not referenced in the current +dictionary. It is stored as the word 257. You write now in the output stream 89 +(ASCII of "Y"). "XY" is now met. But now "XY" is known as the reference 256. +Being that "XY" exists, you test the sequence with one more letter, i.e. "XYZ". +This last word is not referenced in the current dictionary. You write then the +value 256. Finally, you reach the last letter ("Z"). You add "YZ" as the +reference 258 but it is the last letter. That is why you just write the value +90 (ASCII of "Z"). + +Another encoding sample with the string "ABADABCCCABCEABCECCA". + ++----+-----+---------------+------+----------+-------------------------+------+ +|Step|Input|Dictionary test|Prefix|New symbol|Dictionary |Output| +| | | | | |D0=ASCII with 256 letters| | ++----+-----+---------------+------+----------+-------------------------+------+ +| 1 | "A" |"A" in D0 | "A" | "B" | D1=D0 | 65 | +| | "B" |"AB" not in D0 | | | and "AB"=256 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 2 | "A" |"B" in D1 | "B" | "A" | D2=D1 | 66 | +| | |"BA" not in D1 | | | and "BA"=257 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 3 | "D" |"A" in D2 | "A" | "D" | D3=D2 | 65 | +| | |"AD" not in D2 | | | and "AD"=258 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 4 | "A" |"D" in D3 | "D" | "A" | D4=D3 | 68 | +| | |"DA" not in D3 | | | and "DA"=259 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 5 | "B" |"A" in D4 | "AB" | "C" | D5=D4 | 256 | +| | "C" |"AB" in D4 | | | and "ABC"=260 | | +| | |"ABC" not in D4| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 6 | "C" |"C" in D5 | "C" | "C" | D6=D5 | 67 | +| | |"CC" not in D5 | | | and "CC"=261 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 7 | "C" |"C" in D6 | "CC" | "A" | D7=D6 | 261 | +| | "A" |"CC" in D6 | | | and "CCA"=262 | | +| | |"CCA" not in D6| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 8 | "B" |"A" in D7 | "ABC"| "E" | D8=D7 | 260 | +| | "C" |"AB" in D7 | | | and "ABCE"=263 | | +| | "E" |"ABC" in D7 | | | | | +| | <"ABCE" not in D7| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 9 | "A" |"E" in D8 | "E" | "A" | D9=D8 | 69 | +| | |"EA" not in D8 | | | and "EA"=264 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 10 | "B" |"A" in D9 |"ABCE"| "C" | D10=D9 | 263 | +| | "C" |"AB" in D9 | | | and "ABCEC"=265 | | +| | "E" |"ABC" in D9 | | | | | +| | "C" |"ABCE" in D9 | | | | | +| | <"ABCEC" not in D9> | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 11 | "C" |"C" in D10 | "CCA"| | | 262 | +| | "A" |"CC" in D10 | | | | | +| | <"CCA" not in D10| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ + +You will notice a problem with the above output: How to write a code of 256 +(for example) on 8 bits? It's simple to solve this problem. You just say that +the encoding starts with 9 bits and as you reach the 512th word, you use a +10-bits encoding. With 1024 words, you use 11 bits; with 2048 words, 12 bits; +and so on with all numbers of 2^n (n is positive). To better synchronize +the coder and the decoder with all that, most of implementations use two +additional references. The word 256 is a code of reinitialisation (the codec +must reinitialize completely the current dictionary to its 256 initial letters) +and the word 257 is a code of end of information (no more data to read). +Of course, you start your first new word as the code number 258. + +You can also do so as in the GIF file format and start with an initial +dictionary of 18 words to code an input stream with only letters coded on 4 bits +(you start with codes of 5 bits in the output stream!). The 18 initial words +are: 0 to 15 (initial letters), 16 (reinit the dictionary), and 17 (end of +information). First new word has code 18, second word, code 19, ... + +Important: You can consider that your dictionary is limited to 4096 different +words (as in GIF and TIFF file formats). But if your dictionary is full, you +can decide to send old codes *without* reinitializing the dictionary. All the +decoders must be compliant with this. This enables you to consider that it is +not efficient to reinitialize the full dictionary. Instead of this, you don't +change the dictionary and you send/receive (depending if it's a coder or a +decoder) existing codes in the full dictionary. + +My codecs are able to deal as well with most of initial size of data in the +initial dictionary as with full dictionary. + +Let's see how to decode an LZW encoding. We saw with true dynamical Huffman +scheme that you needed an header in the encoding codes. Any header is useless +in LZW scheme. When two successive bytes are read, the first must exist in the +dictionary. This code can be immediately decoded and written in the output +stream. If the second code is equal or less than the word number in the current +dictionary, this code is decoded as the first one. At the opposite, if the +second code is equal to the word number in dictionary plus one, this means you +have to write a word composed with the word (the sentence, not the code number) +of the last code plus the first character of the last code. In between, you make +appear a new word. This new word is the one you just sent to the output stream, +it means composed by all the letters of the word associated to the first code +and the first letter of the word of the second code. You continue the processing +with the second and third codes read in the input stream (of codes)... + +Example: Let's decode the previous encoding given a bit more above. + ++------+-------+----------------+----------+------------------+--------+ +| Step | Input | Code to decode | New code | Dictionary | Output | ++------+-------+----------------+----------+------------------+--------+ +| 1 | 65 | 65 | 66 | 65,66=256 | "A" | +| | 66 | | | | | ++------+-------+----------------+----------+------------------+--------+ +| 2 | 65 | 66 | 65 | 66,65=257 | "B" | ++------+-------+----------------+----------+------------------+--------+ +| 3 | 68 | 65 | 68 | 65,68=258 | "A" | ++------+-------+----------------+----------+------------------+--------+ +| 4 | 256 | 68 | 256 | 68,65=259 | "D" | ++------+-------+----------------+----------+------------------+--------+ +| 5 | 67 | 256 | 67 | 65,66,67=260 | "AB" | ++------+-------+----------------+----------+------------------+--------+ +| 6 | 261 | 67 | 261 | 67,67=261 | "C" | ++------+-------+----------------+----------+------------------+--------+ +| 7 | 260 | 261 | 260 | 67,67,65=262 | "CC" | ++------+-------+----------------+----------+------------------+--------+ +| 8 | 69 | 260 | 69 | 65,66,67,69=263 | "ABC" | ++------+-------+----------------+----------+------------------+--------+ +| 9 | 263 | 69 | 263 | 69,65=264 | "E" | ++------+-------+----------------+----------+------------------+--------+ +| 10 | 262 | 263 | 262 |65,66,67,69,67=256| "ABCE" | ++------+-------+----------------+----------+------------------+--------+ +| 11 | | 262 | | | "CCA" | ++------+-------+----------------+----------+------------------+--------+ + +Summary: The step 4 is an explicit example. The code to decode is 68 ("D" in +ASCII) and the new code is 256. The new word to add to the dictionary is the +letters of the first word plus the the first letter of the second code (code +256), i.e. 65 ("A" in ASCII) plus 68 ("D"). So the new word has the letters 68 +and 65 ("AD"). + +The step 6 is quite special. The first code to decode is referenced but the +second new code is not referenced being that the dictionary is limited to 260 +referenced words. We have to make it as the second previously given case, it +means you must take the word to decode plus its first letter, i.e. "C"+"C"="CC". +Be care, if any encountered code is *upper* than the dictionary size plus 1, it +means you have a problem in your data and/or your codecs are...bad! + +Tricks to improve LZW encoding (but it becomes a non-standard encoding): +- To limit the dictionary to an high amount of words (4096 words maximum enable +you to encode a stream of a maximmum 7,370,880 letters with the same dictionary) +- To use a dictionary of less than 258 if possible (example, with 16 color +pictures, you start with a dictionary of 18 words) +- To not reinitialize a dictionary when it is full +- To reinitialize a dictionary with the most frequent of the previous dictionary +- To use the codes from (current dictionary size+1) to (maximum dictionary size) +because these codes are not used in the standard LZW scheme. +Such a compression scheme has been used (successfully) by Robin Watts +. + ++==========================================================+ +| Summary | ++==========================================================+ + +------------------------------------------------- +RLE type 1: +Fastest compression. Good ratio for general purpose. +Doesn't need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 2: +Fast compression. Very good ratio in general (even for general purposes). +Need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 3: +Slowest compression. Good ratio on image file,quite middle for general purposes. +Need to read the data by twice. +Change line: +#define MAX_RASTER_SIZE 256 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +RLE type 4: +Slow compression. Good ratio on image file, middle in general purposes. +Change line: +#define MAX_RASTER_SIZE 66 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +Huffman: +Fast compression. Good ratio on text files and similar, middle for general +purposes. Interesting method to use to compress a buffer already compressed by +RLE types 1 or 2 methods... +Decoding fast. +------------------------------------------------- +LZW: +Quite fast compression. Good, see even very good ratio, for general purposes. +Bigger the data are, better the compression ratio is. +Decoding quite fast. +------------------------------------------------- + +The source codes work on all kinds of computers with a C compiler. +With the compiler, optimize the speed run option instead of space option. +With UNIX system, it's better to compile them with option -O. +If you don't use a GNU compiler, the source file MUST NOT have a size +over 4 Gb for RLE 2, 3, and Huffman, because I count the number +of occurrences of the bytes. +So, with GNU compilers, 'unsigned lont int' is 8 bytes instead of 4 bytes +(as normal C UNIX compilers and PCs' compilers, such as Microsoft C++ +and Borland C++). +Actually: +* Normal UNIX compilers, => 4 Gb (unsigned long int = 4 bytes) + Microsoft C++ and Borland C++ for PCs +* GNU UNIX compilers => 17179869184 Gb (unsigned long int = 8 bytes) + ++==========================================================+ +| END | ++==========================================================+ diff --git a/baseline/source/huff_dec/huff_dec.c b/baseline/source/huff_dec/huff_dec.c new file mode 100644 index 0000000..48bdf4b --- /dev/null +++ b/baseline/source/huff_dec/huff_dec.c @@ -0,0 +1,393 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: huff_dec + + Author: David Bourgin (David.Bourgin@ufrima.imag.fr) + + Function: Example of Huffman decoding + + Source: ftp://turing.imag.fr/pub/compression/ (1994-09-26) + + Original name: dcodhuff.c + + Changes: I/O to char arrays instead of file i/o. + Dynamic memory allocation replaced by array. + + License: + +The source code files (codrl1.c, dcodrl1.c, codrle2.c, dcodrle2.c, codrle3.c, +dcodrle3.c, codrle4.c, dcodrle4.c, codhuff.c, dcodhuff.c) are copyrighted. +They have been uploaded on ftp in turing.imag.fr (129.88.31.7):/pub/compression +on 22/5/94 and have been modified on 22/9/94. +(c) David Bourgin - 1994 +The source codes I provide have no buggs (!) but being that I make them +available for free I have some notes to make. They can change at any time +without notice. I assume no responsability or liability for any errors or +inaccurracies, make no warranty of any kind (express, implied or statutory) +with respect to this publication and expressly disclaim any and all warranties +of merchantability, fitness for particular purposes. Of course, if you have +some problems to use the information presented here, I will try to help you if +I can. + +If you include the source codes in your application, here are the conditions: +- You have to put my name in the header of your source file (not in the +excutable program if you don't want) (this item is a must) +- I would like to see your resulting application, if possible (this item is not +a must, because some applications must remain secret) +- Whenever you gain money with your application, I would like to receive a very +little part in order to be encouraged to update my source codes and to develop +new schemes (this item is not a must) + +*/ + + +/* + Declaration of types +*/ + + +#include "../extra.h" +typedef struct s_tree { + unsigned int byte; /* A byte has to be coded as an unsigned integer to + allow a node to have a value over 255 */ + struct s_tree *left_ptr; + struct s_tree *right_ptr; +} huff_dec_t_tree; + +typedef struct { + unsigned char bits[32]; + unsigned int bits_nb; + unsigned char presence; +} t_bin_val; + + +/* + Forward declaration of functions +*/ + +void huff_dec_init( void ); +int huff_dec_return( void ); +int huff_dec_end_of_data(); +int huff_dec_read_byte(); +void huff_dec_write_byte( char ch ); +unsigned char huff_dec_read_code_1_bit(); +unsigned int huff_dec_read_code_n_bits( unsigned int n ); +void huff_dec_read_header( t_bin_val codes_table[257] ); +huff_dec_t_tree *huff_dec_tree_encoding( t_bin_val codes_table[257], + huff_dec_t_tree heap[514] ); +void huff_dec_main( void ); +//int main( void ); + + +/* + Declaration of global variables +*/ + +static int huff_dec_input_pos; +static int huff_dec_output_pos; +static char huff_dec_output[1024]; +unsigned char huff_dec_byte_nb_to_read = 0; +unsigned int huff_dec_val_to_read = 0; + + +/* + Initialization- and return-value-related functions +*/ + +#define huff_dec_plaintext_len 600 +static const char *huff_dec_plaintext = + "You are doubtless asking \"How can I reduce the data size without losing " + "some informations?\". It's easy to answer to this question. I'll only take " + "an example. I'm sure you have heard about the morse. This system established " + "in the 19th century use a scheme very close to the huffman one. In the morse " + "you encode the letters to transmit with two kinds of signs. If you encode " + "these two sign possibilities in one bit, the symbol 'e' is transmitted in a " + "single bit and the symbols 'y' and 'z' need four bits. Look at the symbols " + "in the text you are reading, you'll fast understand the compression ratio..."; + +#define huff_dec_encoded_len 419 +static unsigned char huff_dec_encoded[huff_dec_encoded_len] = { + 128, 0, 0, 0, 80, 133, 32, 32, 128, 100, 4, 32, 63, 239, 255, 240, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 7, 167, 21, 129, 232, 69, 120, 132, 217, 20, 162, 19, 164, 39, 133, + 252, 138, 105, 20, 194, 19, 129, 240, 172, 138, 248, 150, 11, 11, 240, 201, + 68, 64, 114, 53, 17, 42, 37, 195, 128, 212, 116, 194, 41, 98, 52, 51, + 12, 132, 112, 244, 3, 36, 33, 52, 39, 135, 164, 33, 62, 156, 87, 14, + 110, 22, 87, 50, 85, 198, 99, 142, 140, 194, 81, 78, 158, 84, 129, 254, + 129, 248, 110, 179, 159, 192, 145, 133, 184, 184, 28, 210, 96, 146, 73, 10, + 226, 21, 83, 152, 74, 13, 111, 132, 199, 202, 219, 241, 74, 193, 167, 105, + 222, 31, 147, 6, 55, 31, 129, 40, 232, 52, 153, 160, 148, 18, 36, 197, + 45, 216, 202, 86, 30, 31, 177, 90, 133, 138, 248, 23, 81, 195, 160, 100, + 215, 93, 50, 185, 225, 251, 23, 6, 230, 225, 229, 112, 71, 80, 96, 141, + 205, 176, 230, 85, 196, 9, 24, 93, 90, 121, 225, 76, 68, 152, 63, 25, + 107, 140, 101, 204, 214, 77, 26, 194, 96, 18, 48, 77, 210, 137, 1, 253, + 4, 230, 248, 56, 240, 224, 111, 163, 95, 10, 12, 223, 7, 234, 167, 129, + 40, 36, 96, 135, 125, 245, 250, 2, 198, 120, 127, 0, 145, 133, 213, 167, + 135, 149, 195, 67, 235, 108, 9, 24, 87, 17, 102, 152, 37, 4, 222, 131, + 188, 144, 73, 36, 128, 73, 20, 81, 152, 177, 133, 248, 28, 165, 131, 120, + 127, 240, 242, 184, 104, 125, 109, 129, 35, 30, 4, 145, 65, 202, 88, 9, + 138, 103, 44, 205, 100, 167, 24, 152, 11, 24, 51, 37, 66, 9, 24, 31, + 174, 202, 212, 49, 152, 18, 96, 155, 208, 119, 146, 45, 97, 48, 56, 28, + 194, 90, 224, 204, 144, 232, 176, 36, 96, 126, 187, 43, 83, 12, 121, 129, + 209, 96, 197, 35, 2, 54, 176, 249, 92, 208, 204, 145, 188, 41, 170, 180, + 71, 16, 36, 96, 126, 187, 43, 83, 19, 0, 145, 129, 100, 209, 15, 43, + 135, 55, 6, 238, 180, 194, 90, 17, 229, 115, 21, 168, 251, 140, 131, 162, + 217, 166, 93, 22, 4, 140, 31, 91, 166, 55, 25, 202, 192, 111, 20, 171, + 207, 39, 192, +}; + + +void huff_dec_init( void ) +{ + huff_dec_input_pos = 0; + huff_dec_output_pos = 0; +} + + +int huff_dec_return( void ) +{ + int i; + _Pragma( "loopbound min 1 max 600" ) + for ( i = 0; i < huff_dec_plaintext_len; i++ ) { + if ( huff_dec_plaintext[i] != huff_dec_output[i] ) return i + 1; + } + return 0; +} + + +/* + Input / output functions +*/ + +int huff_dec_end_of_data() +{ + return huff_dec_input_pos >= huff_dec_encoded_len; +} + + +int huff_dec_read_byte() +{ + return huff_dec_encoded[huff_dec_input_pos++]; +} + + +void huff_dec_write_byte( char ch ) +{ + huff_dec_output[huff_dec_output_pos++] = ch; +} + + +unsigned char huff_dec_read_code_1_bit() +/* Returned parameters: Returns an unsigned integer with the 0-bit (on the + right of the integer) valid + Action: Reads the next bit in the stream of data to compress + Errors: An input/output error could disturb the running of the program + The source must have enough bits to read +*/ +{ + if ( huff_dec_byte_nb_to_read ) { + huff_dec_byte_nb_to_read--; + return ( ( huff_dec_val_to_read >> huff_dec_byte_nb_to_read ) & 1 ); + } else { + huff_dec_val_to_read = huff_dec_read_byte(); + huff_dec_byte_nb_to_read = 7; + return ( ( huff_dec_val_to_read >> 7 ) & 1 ); + } +} + + +unsigned int huff_dec_read_code_n_bits( unsigned int n ) +/* Returned parameters: Returns an unsigned integer with the n-bits (on the + right of the integer) valid + Action: Reads the next n bits in the stream of data to compress + Errors: An input/output error could disturb the running of the program + The source must have enough bits to read +*/ +{ + unsigned int result = 0; + unsigned i = n; + + _Pragma ( "loopbound min 1 max 1" ) + while ( i ) { + _Pragma ( "loopbound min 0 max 2" ) + while ( ( huff_dec_byte_nb_to_read < 9 ) && ( !huff_dec_end_of_data() ) ) { + huff_dec_val_to_read = ( huff_dec_val_to_read << 8 ) + huff_dec_read_byte(); + huff_dec_byte_nb_to_read += 8; + } + if ( i >= huff_dec_byte_nb_to_read ) { + result = ( result << huff_dec_byte_nb_to_read ) + huff_dec_val_to_read; + i -= huff_dec_byte_nb_to_read; + huff_dec_byte_nb_to_read = 0; + } else { + result = ( result << i ) + ( ( huff_dec_val_to_read >> + ( huff_dec_byte_nb_to_read - i ) ) & ( ( 1 << i ) - 1 ) ); + huff_dec_byte_nb_to_read -= i; + i = 0; + } + } + return ( result ); +} + + +void huff_dec_read_header( t_bin_val codes_table[257] ) +/* Returned parameters: The contain of 'codes_table' is modified + Action: Rebuilds the binary encoding array by using the header + Errors: An input/output error could disturb the running of the program +*/ +{ + unsigned int i, j; + unsigned num_byte; + + _Pragma ( "loopbound min 257 max 257" ) + for ( i = 0; i < 257; i++ ) { + codes_table[i].bits_nb = 0; + _Pragma ( "loopbound min 32 max 32" ) + for ( j = 0; j < 32; j++ ) { + codes_table[i].bits[j] = 0; + } + } + + /* == Decoding of the first part of the header === */ + if ( huff_dec_read_code_1_bit() ) + /* First bit=0 => Present bytes coded on n*8 bits + =1 => Present bytes coded on 256 bits */ + _Pragma ( "loopbound min 256 max 256" ) + for ( i = 0; i <= 255; i++ ) + codes_table[i].presence = huff_dec_read_code_1_bit(); + else { + i = huff_dec_read_code_n_bits( 5 ) + 1; + _Pragma ( "loopbound min 1 max 32" ) + while ( i ) { + codes_table[huff_dec_read_code_n_bits( 8 )].presence = 1; + i--; + } + } + codes_table[256].presence = 1; + /* Presence of a fictive 256-byte is enforced! */ + + /* == Decoding the second part of the header == */ + _Pragma ( "loopbound min 257 max 257" ) + for ( i = 0; i <= 256; i++ ) + if ( codes_table[i].presence ) { + if ( huff_dec_read_code_1_bit() ) + /* First bit=0 => 5 bits of binary length-1 followed by a binary word + =1 => 8 bits of binary length-1 followed by a binary word */ + j = huff_dec_read_code_n_bits( 8 ) + 1; + else j = huff_dec_read_code_n_bits( 5 ) + 1; + codes_table[i].bits_nb = j; + /* Reading of a binary word */ + num_byte = ( j - 1 ) >> 3; + if ( j & 7 ) { + /* Reads the bits that takes less than one byte */ + codes_table[i].bits[num_byte] = + ( unsigned char )huff_dec_read_code_n_bits( j & 7 ); + j -= j & 7; + num_byte--; + } + + _Pragma ( "loopbound min 0 max 1" ) + while ( j >= 8 ) { + /* Reads the bits that takes one byte, at least */ + codes_table[i].bits[num_byte] = + ( unsigned char )huff_dec_read_code_n_bits( 8 ); + j -= 8; + num_byte--; + } + } +} + + +huff_dec_t_tree *huff_dec_tree_encoding( t_bin_val codes_table[257], + huff_dec_t_tree heap[514] ) +/* Returned parameters: A binary tree is returned + Action: Returns the decoding binary tree built from 'codes_table' + Errors: None +*/ +{ + unsigned int i; + unsigned int j; + unsigned int heap_top = 0; + huff_dec_t_tree *ptr_tree; + huff_dec_t_tree *current_node; + + ptr_tree = &heap[heap_top++]; + ptr_tree->byte = 257; + ptr_tree->left_ptr = 0; + ptr_tree->right_ptr = 0; + _Pragma ( "loopbound min 257 max 257" ) + for ( i = 0; i <= 256; i++ ) { + _Pragma ( "loopbound min 0 max 9" ) + for ( current_node = ptr_tree, j = codes_table[i].bits_nb; j; j-- ) { + if ( codes_table[i].bits[( j - 1 ) >> 3] & ( 1 << ( ( + j - 1 ) & 7 ) ) ) + if ( current_node->left_ptr == 0 ) { + current_node->left_ptr = &heap[heap_top++]; + current_node = current_node->left_ptr; + current_node->left_ptr = 0; + current_node->right_ptr = 0; + } else current_node = current_node->left_ptr; + else + if ( current_node->right_ptr == 0 ) { + current_node->right_ptr = &heap[heap_top++]; + current_node = current_node->right_ptr; + current_node->left_ptr = 0; + current_node->right_ptr = 0; + } else current_node = current_node->right_ptr; + if ( j == 1 ) + current_node->byte = i; + else current_node->byte = 257; + } + }; + return ( ptr_tree ); +} + + +void _Pragma( "entrypoint" ) huff_dec_main( void ) +/* Returned parameters: None + Action: Decompresses with Huffman method all bytes read by the function + 'read_code_1_bit' and 'read_code_n_bits' + Errors: An input/output error could disturb the running of the program +*/ +{ + t_bin_val encoding_table[257]; + huff_dec_t_tree heap[514]; /* space for dynamically allocated nodes */ + huff_dec_t_tree *ptr_tree; + huff_dec_t_tree *current_node; + + if ( !huff_dec_end_of_data() ) { /* Are there data to compress? */ + huff_dec_read_header( encoding_table ); + ptr_tree = huff_dec_tree_encoding( encoding_table, heap ); + _Pragma ( "loopbound min 602 max 602" ) + do { + current_node = ptr_tree; + _Pragma ( "loopbound min 3 max 9" ) + while ( current_node->byte == 257 ) + if ( huff_dec_read_code_1_bit() ) + /* Bit=1 => Got to left in the node of the tree + =0 => Got to right in the node of the tree */ + current_node = current_node->left_ptr; + else current_node = current_node->right_ptr; + if ( current_node->byte <= 255 ) + huff_dec_write_byte( current_node->byte ); + } while ( current_node->byte != 256 ); + } +} + + +int main( int argc, char **argv ) +{ + //SET_UP + int jobsComplete; + int maxJobs=5; + for (jobsComplete=-1; jobsCompletesource_memory_end) +#define read_byte() (*(source_ptr++)) + +If you want to compress *to* memory, before entering in a xxxcoding procedure +('xxx' is the actual extension to replace with a given codec), you have to add +a pointer. Note that the pointer 'dest_memory_base' is not to add, it is just +given there to specify the address of the destination memory zone you are +going to encode or decode. + +unsigned char *dest_memory_base, /* Base of the destination memory */ + *dest_ptr; /* Used in the xxxcoding procedure */ +void pre_start() +{ dest_ptr=dest_memory_base; + xxxcoding(); +} + +Of course, you can combine both from and to memory in the pre_start() procedure. +The files dest_file and source_file handled in the main() function are +to remove... + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + xxxcoding(); +} + +In fact, to write to memory, the problem is in the write_byte(x) procedure. +This problem exists because your destination zone can either be a static +zone or a dynamically allocated zone. In the two cases, you have to check +if there is no overflow, especially if the coder is not efficient and must +produce more bytes than you reserved in memory. + +In the first case, with a *static* zone, write_byte(x) macro should look like +that: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + exit(1); \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +In the static version, the pre_start() procedure is to modify as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=...; /* Set up to the actual destination zone length */ + current_size=0; /* Number of written bytes */ + xxxcoding(); +} +Otherwise, dest_ptr is a zone created by the malloc instruction and you can try +to resize the allocated zone with the realloc instruction. Note that I increment +the zone one kilo-bytes by one kylo-bytes. You have to add two other variables: + +unsigned long int dest_zone_length, + current_size; + +#define write_byte(x) { if (current_size==dest_zone_length) \ + { dest_zone_length += 1024; \ + if ((dest_ptr=(unsigned char *)realloc(dest_ptr,dest_zone_length*sizeof(unsigned char)))==NULL) \ + exit(1); /* You can't compress in memory \ + => I exit but *you* can make a routine to swap on disk */ \ + } \ + dest_ptr[current_size++]=(unsigned char)(x); \ + } + +With the dynamically allocated version, change the pre_start() routine as following: + +void pre_start() +{ source_ptr=source_memory_base; + dest_ptr=dest_memory_base; + dest_zone_length=1024; + if ((dest_ptr=(unsigned char *)malloc(dest_zone_length*sizeof(unsigned char)))==NULL) + exit(1); /* You need at least 1 kb in the dynamical memory ! */ + current_size=0; /* Number of written bytes */ + xxxcoding(); + /* Handle the bytes in dest_ptr but don't forget to free these bytes with: + free(dest_ptr); + */ +} + +The previously given macros work as: + +void demo() /* The file opening, closing and variables + must be set up by the calling procedure */ +{ unsigned char byte; + /* And not 'char byte' (!) */ + while (!end_of_data()) + { byte=read_byte(); + printf("Byte read=%c\n",byte); + } +} + +You must not change the rest of the program unless you're really sure and +really need to do it! + ++==========================================================+ +| The RLE encoding | ++==========================================================+ + +RLE is an acronym that stands for Run Length Encoding. You may encounter it +as an other acronym: RLC, Run Length Coding. + +The idea in this scheme is to recode your data with regard to the repetition +frames. A frame is one or more bytes that occurr one or several times. + +There are several means to encode occurrences. So, you'll have several codecs. +For example, you may have a sequence such as: +0,0,0,0,0,0,255,255,255,2,3,4,2,3,4,5,8,11 + +Some codecs will only deal with the repetitions of '0' and '255' but some other +will deal with the repetitions of '0', '255', and '2,3,4'. + +You have to keep in your mind something important based on this example. A codec +won't work on all the data you will try to compress. So, in case of non +existence of sequence repetitions, the codecs based on RLE schemes must not +display a message to say: "Bye bye". Actually, they will try to encode these +non repeted data with a value that says "Sorry, I only make a copy of the inital +input". Of course, a copy of the input data with an header in front of this copy +will make a biggest output data but if you consider the whole data to compress, +the encoding of repeated frames will take less space than the encoding +of non-repeated frames. + +All of the algorithms with the name of RLE have the following look with three +or four values: +- Value saying if there's a repetition +- Value saying how many repetitions (or non repetition) +- Value of the length of the frame (useless if you just encode frame +with one byte as maximum length) +- Value of the frame to repeat (or not) + +I gave four algorithms to explain what I say. + +*** First RLE scheme *** + +The first scheme is the simpliest I know, and looks like the one used in MAC +system (MacPackBit) and some image file formats such as Targa, PCX, TIFF, ... + +Here, all compressed blocks begin with a byte, named header, which description +is: + +Bits 7 6 5 4 3 2 1 0 +Header X X X X X X X X + +Bits 7: Compression status (1=Compression applied) + 0 to 6: Number of bytes to handle + +So, if the bit 7 is set up to 0, the 0 to 6 bits give the number of bytes +that follow (minus 1, to gain more over compress) and that were not compressed +(native bytes). If the bit 7 is set up to 1, the same 0 to 6 bits give +the number of repetition (minus 2) of the following byte. + +As you see, this method only handle frame with one byte. + +Additional note: You have 'minus 1' for non-repeated frames because you must +have at least one byte to compress and 'minus 2' for repeated frames because the +repetition must be 2, at least. + +Compression scheme: + + First byte=Next + /\ + / \ +Count the byte Count the occurrence of NON identical +occurrences bytes (maximum 128 times) +(maximum 129 times) and store them in an array + | | + | | + 1 bit '1' 1 bit '0' ++ 7 bits giving + 7 bits giving + the number (-2) the number (-1) + of repetitions of non repetition ++ repeated byte + n non repeated bytes + | | + 1xxxxxxx,yyyyyyyy 0xxxxxxx,n bytes +[-----------------] [----------------] + +Example: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 1,255,15, | -1 + 255,255, | 128,255, | 0 + 15,15, | 128,15, | 0 + 255,255,255, | 129,255, | +1 + 15,15,15, | 129,15, | +1 + 255,255,255,255, | 130,255, | +2 + 15,15,15,15 | 130,15 | +2 + +See codecs source codes: codrle1.c and dcodrle1.c + +*** Second RLE scheme *** + +In the second scheme of RLE compression you look for the less frequent byte +in the source to compress and use it as an header for all compressed block. + +In the best cases, the occurrence of this byte is zero in the data to compress. + +Two possible schemes, firstly with handling frames with only one byte, +secondly with handling frames with one byte *and* more. The first case is +the subject of this current compression scheme, the second is the subject +of next compression scheme. + +For the frame of one byte, header byte is written in front of all repetition +with at least 4 bytes. It is then followed by the repetition number minus 1 and +the repeated byte. +Header byte, Occurrence number-1, repeated byte + +If a byte don't repeat more than tree times, the three bytes are written without +changes in the destination stream (no header nor length, nor repetition in front +or after theses bytes). + +An exception: If the header byte appears in the source one, two, three and up +times, it'll be respectively encoded as following: +- Header byte, 0 +- Header byte, 1 +- Header byte, 2 +- Header byte, Occurrence number-1, Header byte + +Example, let's take the previous example. A non frequent byte is zero-ASCII +because it never appears. + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 255,15, | 255,15, | -1 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 0,3,255, | -1 + 15,15,15,15 | 0,3,15 | -1 + +If the header would appear, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +------------------------------------------------------------------------- + 0, | 0,0, | +1 + 255, | 255, | 0 + 0,0, | 0,1, | 0 + 15, | 15, | 0 + 0,0,0, | 0,2, | -1 + 255, | 255, | 0 + 0,0,0,0 | 0,3,0 | -1 + +See codecs source codes: codrle2.c and dcodrle2.c + +*** Third RLE scheme *** + +It's the same idea as the second scheme but we can encode frames with +more than one byte. So we have three cases: + +- If it was the header byte, whatever is its occurrence, you encode it with: +Header byte,0,number of occurrence-1 +- For frames which (repetition-1)*length>3, encode it as: +Header byte, Number of frame repetition-1, frame length-1,bytes of frame +- If no previous cases were detected, you write them as originally (no header, +nor length, nor repetition in front or after theses bytes). + +Example based on the previous examples: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +----------------------------------------------------------------------------- + 255,15, | 255,15, | 0 + 255,255, | 255,255, | 0 + 15,15, | 15,15, | 0 + 255,255,255, | 255,255,255, | 0 + 15,15,15, | 15,15,15, | 0 + 255,255,255,255, | 255,255,255,255, | 0 + 15,15,15,15, | 15,15,15,15, | 0 + 16,17,18,16,17,18, |16,17,18,16,17,18,| 0 + 255,255,255,255,255, | 0,4,0,255, | -1 + 15,15,15,15,15, | 0,4,0,15, | -1 + 16,17,18,16,17,18,16,17,18,| 0,2,2,16,17,18, | -3 + 16,17,18,19,16,17,18,19 |0,1,3,16,17,18,19 | -1 + +If the header (value 0) would be met, we would see: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 0, | 0,0,0, | +2 + 255, | 255, | 0 + 0,0, | 0,0,1, | +1 + 15, | 15, | 0 + 0,0,0, | 0,0,2, | 0 + 255, | 255, | 0 + 0,0,0,0 | 0,0,3 | -1 + +See codecs source codes: codrle3.c and dcodrle3.c + +*** Fourth RLE scheme *** + +This last RLE algorithm better handles repetitions of any kind (one byte +and more) and non repetitions, including few non repetitions, and does not +read the source by twice as RLE type 3. + +Compression scheme is: + + First byte=Next byte? + /\ + Yes / \ No + / \ + 1 bit '0' 1 bit '1' + / \ + / \ + Count the Motif of several + occurrences repeated byte? + of 1 repeated ( 65 bytes repeated + byte (maximum 257 times maxi) + 16449 times) /\ + /\ / \ + / \ / \ + / \ / \ + / \ / \ + 1 bit '0' 1 bit '1' 1 bit '0' 1 bit '1' ++ 6 bits + 14 bits + 6 bits of | +giving the giving the the length Number of non repetition +length (-2) length (-66) of the motif (maximum 8224) +of the of the + 8 bits of /\ +repeated byte repeated byte the number (-2) < 33 / \ > 32 ++ repeated byte + repeated byte of repetition / \ + | | + bytes of the 1 bit '0' 1 bit '1' + | | motif + 5 bits of + 13 bits + | | | the numer (-1) of the + | | | of non number (-33) + | | | repetition of repetition + | | | + non + non + | | | repeated repeated + | | | bytes bytes + | | | | | + | | | | 111xxxxx,xxxxxxxx,n bytes + | | | | [-------------------------] + | | | | + | | | 110xxxxx,n bytes + | | | [----------------] + | | | + | | 10xxxxxx,yyyyyyyy,n bytes + | | [-------------------------] + | | + | 01xxxxxx,xxxxxxxx,1 byte + | [------------------------] + | + 00xxxxxx,1 byte +[---------------] + +Example, same as previously: + +Sequence of bytes to encode | Coded values | Differences with compression + | | (unit: byte) +-------------------------------------------------------------------------- + 255,15 | 11000001b,255,15, | +1 + 255,255 | 00000000b,255, | 0 + 15,15 | 00000000b,15, | 0 + 255,255,255 | 00000001b,255, | -1 + 15,15,15 | 00000001b,15, | -1 + 255,255,255,255 | 00000010b,255, | -2 + 15,15,15,15 | 00000010b,15, | -2 + 16,17,18,16,17,18 |10000001b,0,16,17,18,| -1 + 255,255,255,255,255 | 00000011b,255, | -3 + 15,15,15,15,15 | 00000011b,15, | -3 + 16,17,18,16,17,18,16,17,18 | 10000001b,16,17,18, | -4 + 16,17,18,19,16,17,18,19 |10000010b,16,17,18,19| -2 + ++==========================================================+ +| The Huffman encoding | ++==========================================================+ + +This method comes from the searcher who established the algorithm in 1952. +This method allows both a dynamic and static statistic schemes. A statistic +scheme works on the data occurrences. It is not as with RLE where you had +a consideration of the current occurrence of a frame but rather a consideration +of the global occurrences of each data in the input stream. In this last case, +frames can be any kinds of sequences you want. On the other hand, Huffman +static encoding appears in some compressers such as ARJ on PCs. This enforces +the encoder to consider every statistic as the same for all the data you have. +Of course, the results are not as good as if it were a dynamic encoding. +The static encoding is faster than the dynamic encoding but the dynamic encoding +will be adapted to the statistic of the bytes of the input stream and will +of course become more efficient by producing shortest output. + +The main idea in Huffman encoding is to re-code every byte with regard to its +occurrence. The more frequent bytes in the data to compress will be encoded with +less than 8 bits and the others could need 8 bits see even more to be encoded. +You immediately see that the codes associated to the different bytes won't have +identical size. The Huffman method will actually require that the binary codes +have not a fixed size. We speak then about variable length codes. + +The dynamical Huffman scheme needs the binary trees for the encoding. This +enables you to obtain the best codes, adapted to the source data. +The demonstration won't be given there. To help the neophyt, I will just explain +what is a binary tree. + +A binary tree is special fashion to represent the data. A binary tree is +a structure with an associated value with two pointers. The term of binary has +been given because of the presence of two pointers. Because of some conventions, +one of the pointer is called left pointer and the second pointer is called right +pointer. Here is a visual representation of a binary tree. + + Value + / \ + / \ + Value Value + / \ / \ +... ... ... ... + +One problem with a binary encoding is a prefix problem. A prefix is the first +part of the representation of a value, e.g. "h" and "he" are prefixes of "hello" +but not "el". To understand the problem, let's code the letters "A", "B", "C", +"D", and "E" respectively as 00b, 01b, 10b, 11b, and 100b. When you read +the binary sequence 00100100b, you are unable to say if this comes from "ACBA" +or "AEE". To avoid such situations, the codes must have a prefix property. +And the letter "E" mustn't begin with the sequence of an other code. With "A", +"B", "C", "D", and "E" respectively affected with 1b, 01b, 001b, 0001b, and +0000b, the sequence 1001011b will only be decoded as "ACBA". + + 1 0 +<- /\ -> + / \ + "A" /\ + "B" \ + /\ + "C" \ + /\ + "D" "E" + +As you see, with this tree, an encoding will have the prefix property +if the bytes are at the end of each "branch" and you have no byte at the "node". +You also see that if you try to reach a character by the right pointer you add +a bit set to 0 and by the left pointer, you add a bit set to 1 to the current +code. The previous *bad* encoding provide the following bad tree: + + /\ + / \ + / \ + /\ /\ + / \ "B" "A" + / \ +"D" "C"\ + / \ + "E" + +You see here that the coder shouldn't put the "C" at a node... + +As you see, the largest binary code are those with the longest distance +from the top of the tree. Finally, the more frequent bytes will be the highest +in the tree in order you have the shortest encoding and the less frequent bytes +will be the lowest in the tree. + +From an algorithmic point of view, you make a list of each byte you encountered +in the stream to compress. This list will always be sorted. The zero-occurrence +bytes are removed from this list. You take the two bytes with the smallest +occurrences in the list. Whenever two bytes have the same "weight", you take two +of them regardless to their ASCII value. You join them in a node. This node will +have a fictive byte value (256 will be a good one!) and its weight will be +the sum of the two joined bytes. You replace then the two joined bytes with +the fictive byte. And you continue so until you have one byte (fictive or not) +in the list. Of course, this process will produce the shortest codes if the list +remains sorted. I will not explain with arcana hard maths why the result +is a set of the shortest bytes... + +Important: I use as convention that the right sub-trees have a weight greater +or equal to the weight of the left sub-trees. + +Example: Let's take a file to compress where we notice the following +occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +We will begin by joining the bytes 83 and 222. This will produce a fictive node +1 with a weight of 20+5=25. + +(Fictive 1,25) + /\ + / \ +(222,5) (83,20) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 1 | 25 + 77 | 24 + 115 | 21 + +Note that the list is sorted... The smallest values in the frequences are 21 and +24. That is why we will take the bytes 77 and 115 to build the fictive node 2. + +(Fictive 2,45) + /\ + / \ +(115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 2 | 45 + Fictive 1 | 25 + +The nodes with smallest weights are the fictive 1 and 2 nodes. These are joined +to build the fictive node 3 whose weight is 40+25=70. + + (Fictive 3,70) + / \ + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + 0 | 338 + 255 | 300 + 31 | 280 + Fictive 3 | 70 + +The fictive node 3 is linked to the byte 31. Total weight: 280+70=350. + + (Fictive 4,350) + / \ + / \ + / \ + / \ (31,280) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 4 | 350 + 0 | 338 + 255 | 300 + +As you see, being that we sort the list, the fictive node 4 has become the first +of the list. We join the bytes 0 and 255 in a same fictive node, the number 5 +whose weight is 338+300=638. + +(Fictive 5,638) + /\ + / \ +(255,300) (0,338) + +Listed bytes | Frequences (Weight) +---------------------------------- + Fictive 5 | 638 + Fictive 4 | 350 + +The fictive nodes 4 and 5 are finally joined. Final weight: 638+350=998 bytes. +It is actually the total byte number in the initial file: 338+300+24+21+20+5. + + (Tree,998) + 1 / \ 0 + <- / \ -> + / \ + / \ + / \ + / \ / \ + / \ / \ + / \ / \ + / \ (31,280) (255,300) (0,338) + / \ + / \ + /\ / \ + / \ / \ +(222,5) (83,20) (115,21) (77,25) + +Bytes | Huffman codes | Frequences | Binary length*Frequence +------------------------------------------------------------ + 0 | 00b | 338 | 676 + 255 | 01b | 300 | 600 + 31 | 10b | 280 | 560 + 77 | 1101b | 24 | 96 + 115 | 1100b | 21 | 84 + 83 | 1110b | 20 | 80 + 222 | 1111b | 5 | 20 + +Results: Original file size: (338+300+280+24+21+20+5)*8=7904 bits (=998 bytes) +versus 676+600+560+96+84+80+20=2116 bits, i.e. 2116/8=265 bytes. + +Now you know how to code an input stream. The last problem is to decode all this +stuff. Actually, when you meet a binary sequence you can't say whether it comes +from such byte list or such other one. Furthermore, if you change the occurrence +of one or two bytes, you won't obtain the same resulting binary tree. Try for +example to encode the previous list but with the following occurrences: + +Listed bytes | Frequences (Weight) +---------------------------------- + 255 | 418 + 0 | 300 + 31 | 100 + 77 | 24 + 115 | 21 + 83 | 20 + 222 | 5 + +As you can observe it, the resulting binary tree is quite different, we had yet +the same initial bytes. To not be in such a situation we will put an header +in front of all data. I can't comment longly this header but I can say +I minimize it as much as I could. The header is divided into two parts. +The first part of this header looks closely to a boolean table (coded more or +less in binary to save space) and the second part provide to the decoder +the binary code associated to each byte encountered in the original input +stream. + +Here is a summary of the header: + +First part +---------- + First bit + / \ + 1 / \ 0 + / \ + 256 bits set to 0 or 1 5 bits for the number n (minus 1) + depending whether the of bytes encountered + corresponding byte was in the file to compres + in the file to compress | + (=> n bits set to 1, \ / + n>32) n values of 8-bits (n<=32) + \ / + \ / + \ / +Second part | +----------- | + | + +------------->| +(n+1) times | | +(n bytes of | First bit? +the values | / \ +encountered | 1 / \ 0 +in the | / \ +source file | 8 bits of 5 bits of the ++ the code | the length length (-1) +of a | (-1) of the of the following +fictive | following binary +byte | binary code code +to stop the | (length>32) (length<=32) +decoding. | \ / +The fictive | \ / +is set to | \ / +256 in the | | +Huffman | binary code +-tree of | | +encoding) +--------------| + | + Binary encoding of the source file + | + Code of end of encoding + | + + +With my codecs I can handle binary sequences with a length of 256 bits. +This correspond to encode all the input stream from one byte to infinite length. +In fact if a byte had a range from 0 to 257 instead of 0 to 255, I would have a +bug with my codecs with an input stream of at least 370,959,230,771,131,880,927, +453,318,055,001,997,489,772,178,180,790,105 bytes !!! + +Where come this explosive number? In fact, to have a severe bug, I must have +a completely unbalanced tree: + + Tree + /\ + \ + /\ + \ + /\ + \ + ... + /\ + \ + /\ + +Let's take the following example: + +Listed bytes | Frequences (Weight) +---------------------------------- + 32 | 5 + 101 | 3 + 97 | 2 + 100 | 1 + 115 | 1 + +This produces the following unbalanced tree: + + Tree + /\ +(32,5) \ + /\ + (101,3) \ + /\ + (97,2) \ + /\ + (115,1) (100,1) + +Let's speak about a mathematical series: The Fibonacci series. It is defined as +following: + +{ Fib(0)=0 +{ Fib(1)=1 +{ Fib(n)=Fib(n-2)+Fib(n-1) + +Fib(0)=0, Fib(1)=1, Fib(2)=1, Fib(3)=2, Fib(4)=3, Fib(5)=5, Fib(6)=8, Fib(7)=13, +etc. + +But 1, 1, 2, 3, 5, 8 are the occurrences of our list! We can actually +demonstrate that to have an unbalanced tree, we have to take a list with +an occurrence based on the Fibonacci series (these values are minimal). +If the data to compress have m different bytes, when the tree is unbalanced, +the longest code need m-1 bits. In our little previous example where m=5, +the longest codes are associated to the bytes 100 and 115, respectively coded +0001b and 0000b. We can also say that to have an unbalanced tree we must have +at least 5+3+2+1+1=12=Fib(7)-1. To conclude about all that, with a coder that +uses m-1 bits, you must never have an input stream size over than Fib(m+2)-1, +otherwise, there could be a bug in the output stream. Of course, with my codecs +there will never be a bug because I can deal with binary code sizes of 1 to 256 +bits. Some encoder could use that with m=31, Fib(31+2)-1=3,524,577 and m=32, +Fib(32+2)-1=5,702,886. And an encoder that uses unisgned integer of 32 bits +shouldn't have a bug until about 4 Gb... + ++==========================================================+ +| The LZW encoding | ++==========================================================+ + +The LZW scheme is due to three searchers, i.e. Abraham Lempel and Jacob Ziv +worked on it in 1977, and Terry Welch achieved this scheme in 1984. + +LZW is patented in USA. This patent, number 4,558,302, is covered by Unisys +Corporation. You can usually write (without fees) software codecs which use +the LZW scheme but hardware companies can't do so. You may get a limited +licence by writting to: +Welch Licencing Department +Office of the General Counsel +M/S C1SW19 +Unisys corporation +Blue Bell +Pennsylvania, 19424 (USA) + +If you're occidental, you are surely using an LZW encoding every time you are +speaking, especially when you use a dictionary. Let's consider, for example, +the word "Cirrus". As you read a dictionary, you begin with "A", "Aa", and so +on. But a computer has no experience and it must suppose that some words +already exist. That is why with "Cirrus", it supposes that "C", "Ci", "Cir", +"Cirr", "Cirru", and "Cirrus" exist. Of course, being that this is a computer, +all these words are encoded as index numbers. Every time you go forward, you add +a new number associated to the new word. Being that a computer is byte-based +and not alphabetic-based, you have an initial dictionary of 256 letters instead +of our 26 ('A' to 'Z') letters. + +Example: Let's code "XYXYZ". First step, "X" is recognized in the initial +dictionary of 256 letters as the 89th. Second step, "Y" is read. Does "XY" +exist? No, then "XY" is stored as the word 256. You write in the output stream +the ASCII of "X", i.e. 88. Now "YX" is tested as not referenced in the current +dictionary. It is stored as the word 257. You write now in the output stream 89 +(ASCII of "Y"). "XY" is now met. But now "XY" is known as the reference 256. +Being that "XY" exists, you test the sequence with one more letter, i.e. "XYZ". +This last word is not referenced in the current dictionary. You write then the +value 256. Finally, you reach the last letter ("Z"). You add "YZ" as the +reference 258 but it is the last letter. That is why you just write the value +90 (ASCII of "Z"). + +Another encoding sample with the string "ABADABCCCABCEABCECCA". + ++----+-----+---------------+------+----------+-------------------------+------+ +|Step|Input|Dictionary test|Prefix|New symbol|Dictionary |Output| +| | | | | |D0=ASCII with 256 letters| | ++----+-----+---------------+------+----------+-------------------------+------+ +| 1 | "A" |"A" in D0 | "A" | "B" | D1=D0 | 65 | +| | "B" |"AB" not in D0 | | | and "AB"=256 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 2 | "A" |"B" in D1 | "B" | "A" | D2=D1 | 66 | +| | |"BA" not in D1 | | | and "BA"=257 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 3 | "D" |"A" in D2 | "A" | "D" | D3=D2 | 65 | +| | |"AD" not in D2 | | | and "AD"=258 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 4 | "A" |"D" in D3 | "D" | "A" | D4=D3 | 68 | +| | |"DA" not in D3 | | | and "DA"=259 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 5 | "B" |"A" in D4 | "AB" | "C" | D5=D4 | 256 | +| | "C" |"AB" in D4 | | | and "ABC"=260 | | +| | |"ABC" not in D4| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 6 | "C" |"C" in D5 | "C" | "C" | D6=D5 | 67 | +| | |"CC" not in D5 | | | and "CC"=261 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 7 | "C" |"C" in D6 | "CC" | "A" | D7=D6 | 261 | +| | "A" |"CC" in D6 | | | and "CCA"=262 | | +| | |"CCA" not in D6| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 8 | "B" |"A" in D7 | "ABC"| "E" | D8=D7 | 260 | +| | "C" |"AB" in D7 | | | and "ABCE"=263 | | +| | "E" |"ABC" in D7 | | | | | +| | <"ABCE" not in D7| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 9 | "A" |"E" in D8 | "E" | "A" | D9=D8 | 69 | +| | |"EA" not in D8 | | | and "EA"=264 | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 10 | "B" |"A" in D9 |"ABCE"| "C" | D10=D9 | 263 | +| | "C" |"AB" in D9 | | | and "ABCEC"=265 | | +| | "E" |"ABC" in D9 | | | | | +| | "C" |"ABCE" in D9 | | | | | +| | <"ABCEC" not in D9> | | | | ++----+-----+---------------+------+----------+-------------------------+------+ +| 11 | "C" |"C" in D10 | "CCA"| | | 262 | +| | "A" |"CC" in D10 | | | | | +| | <"CCA" not in D10| | | | | ++----+-----+---------------+------+----------+-------------------------+------+ + +You will notice a problem with the above output: How to write a code of 256 +(for example) on 8 bits? It's simple to solve this problem. You just say that +the encoding starts with 9 bits and as you reach the 512th word, you use a +10-bits encoding. With 1024 words, you use 11 bits; with 2048 words, 12 bits; +and so on with all numbers of 2^n (n is positive). To better synchronize +the coder and the decoder with all that, most of implementations use two +additional references. The word 256 is a code of reinitialisation (the codec +must reinitialize completely the current dictionary to its 256 initial letters) +and the word 257 is a code of end of information (no more data to read). +Of course, you start your first new word as the code number 258. + +You can also do so as in the GIF file format and start with an initial +dictionary of 18 words to code an input stream with only letters coded on 4 bits +(you start with codes of 5 bits in the output stream!). The 18 initial words +are: 0 to 15 (initial letters), 16 (reinit the dictionary), and 17 (end of +information). First new word has code 18, second word, code 19, ... + +Important: You can consider that your dictionary is limited to 4096 different +words (as in GIF and TIFF file formats). But if your dictionary is full, you +can decide to send old codes *without* reinitializing the dictionary. All the +decoders must be compliant with this. This enables you to consider that it is +not efficient to reinitialize the full dictionary. Instead of this, you don't +change the dictionary and you send/receive (depending if it's a coder or a +decoder) existing codes in the full dictionary. + +My codecs are able to deal as well with most of initial size of data in the +initial dictionary as with full dictionary. + +Let's see how to decode an LZW encoding. We saw with true dynamical Huffman +scheme that you needed an header in the encoding codes. Any header is useless +in LZW scheme. When two successive bytes are read, the first must exist in the +dictionary. This code can be immediately decoded and written in the output +stream. If the second code is equal or less than the word number in the current +dictionary, this code is decoded as the first one. At the opposite, if the +second code is equal to the word number in dictionary plus one, this means you +have to write a word composed with the word (the sentence, not the code number) +of the last code plus the first character of the last code. In between, you make +appear a new word. This new word is the one you just sent to the output stream, +it means composed by all the letters of the word associated to the first code +and the first letter of the word of the second code. You continue the processing +with the second and third codes read in the input stream (of codes)... + +Example: Let's decode the previous encoding given a bit more above. + ++------+-------+----------------+----------+------------------+--------+ +| Step | Input | Code to decode | New code | Dictionary | Output | ++------+-------+----------------+----------+------------------+--------+ +| 1 | 65 | 65 | 66 | 65,66=256 | "A" | +| | 66 | | | | | ++------+-------+----------------+----------+------------------+--------+ +| 2 | 65 | 66 | 65 | 66,65=257 | "B" | ++------+-------+----------------+----------+------------------+--------+ +| 3 | 68 | 65 | 68 | 65,68=258 | "A" | ++------+-------+----------------+----------+------------------+--------+ +| 4 | 256 | 68 | 256 | 68,65=259 | "D" | ++------+-------+----------------+----------+------------------+--------+ +| 5 | 67 | 256 | 67 | 65,66,67=260 | "AB" | ++------+-------+----------------+----------+------------------+--------+ +| 6 | 261 | 67 | 261 | 67,67=261 | "C" | ++------+-------+----------------+----------+------------------+--------+ +| 7 | 260 | 261 | 260 | 67,67,65=262 | "CC" | ++------+-------+----------------+----------+------------------+--------+ +| 8 | 69 | 260 | 69 | 65,66,67,69=263 | "ABC" | ++------+-------+----------------+----------+------------------+--------+ +| 9 | 263 | 69 | 263 | 69,65=264 | "E" | ++------+-------+----------------+----------+------------------+--------+ +| 10 | 262 | 263 | 262 |65,66,67,69,67=256| "ABCE" | ++------+-------+----------------+----------+------------------+--------+ +| 11 | | 262 | | | "CCA" | ++------+-------+----------------+----------+------------------+--------+ + +Summary: The step 4 is an explicit example. The code to decode is 68 ("D" in +ASCII) and the new code is 256. The new word to add to the dictionary is the +letters of the first word plus the the first letter of the second code (code +256), i.e. 65 ("A" in ASCII) plus 68 ("D"). So the new word has the letters 68 +and 65 ("AD"). + +The step 6 is quite special. The first code to decode is referenced but the +second new code is not referenced being that the dictionary is limited to 260 +referenced words. We have to make it as the second previously given case, it +means you must take the word to decode plus its first letter, i.e. "C"+"C"="CC". +Be care, if any encountered code is *upper* than the dictionary size plus 1, it +means you have a problem in your data and/or your codecs are...bad! + +Tricks to improve LZW encoding (but it becomes a non-standard encoding): +- To limit the dictionary to an high amount of words (4096 words maximum enable +you to encode a stream of a maximmum 7,370,880 letters with the same dictionary) +- To use a dictionary of less than 258 if possible (example, with 16 color +pictures, you start with a dictionary of 18 words) +- To not reinitialize a dictionary when it is full +- To reinitialize a dictionary with the most frequent of the previous dictionary +- To use the codes from (current dictionary size+1) to (maximum dictionary size) +because these codes are not used in the standard LZW scheme. +Such a compression scheme has been used (successfully) by Robin Watts +. + ++==========================================================+ +| Summary | ++==========================================================+ + +------------------------------------------------- +RLE type 1: +Fastest compression. Good ratio for general purpose. +Doesn't need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 2: +Fast compression. Very good ratio in general (even for general purposes). +Need to read the data by twice. +Decoding fast. +------------------------------------------------- +RLE type 3: +Slowest compression. Good ratio on image file,quite middle for general purposes. +Need to read the data by twice. +Change line: +#define MAX_RASTER_SIZE 256 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +RLE type 4: +Slow compression. Good ratio on image file, middle in general purposes. +Change line: +#define MAX_RASTER_SIZE 66 +into: +#define MAX_RASTER_SIZE 16 +to speed up the encoding (but the result decreases in ratio). If you compress +with memory buffers, do not modify this line... +Decoding fast. +------------------------------------------------- +Huffman: +Fast compression. Good ratio on text files and similar, middle for general +purposes. Interesting method to use to compress a buffer already compressed by +RLE types 1 or 2 methods... +Decoding fast. +------------------------------------------------- +LZW: +Quite fast compression. Good, see even very good ratio, for general purposes. +Bigger the data are, better the compression ratio is. +Decoding quite fast. +------------------------------------------------- + +The source codes work on all kinds of computers with a C compiler. +With the compiler, optimize the speed run option instead of space option. +With UNIX system, it's better to compile them with option -O. +If you don't use a GNU compiler, the source file MUST NOT have a size +over 4 Gb for RLE 2, 3, and Huffman, because I count the number +of occurrences of the bytes. +So, with GNU compilers, 'unsigned lont int' is 8 bytes instead of 4 bytes +(as normal C UNIX compilers and PCs' compilers, such as Microsoft C++ +and Borland C++). +Actually: +* Normal UNIX compilers, => 4 Gb (unsigned long int = 4 bytes) + Microsoft C++ and Borland C++ for PCs +* GNU UNIX compilers => 17179869184 Gb (unsigned long int = 8 bytes) + ++==========================================================+ +| END | ++==========================================================+ diff --git a/baseline/source/huff_enc/huff_enc.c b/baseline/source/huff_enc/huff_enc.c new file mode 100644 index 0000000..2e739e6 --- /dev/null +++ b/baseline/source/huff_enc/huff_enc.c @@ -0,0 +1,589 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: huff_enc + + Author: David Bourgin (David.Bourgin@ufrima.imag.fr) + + Function: Example of Huffman encoding + + Source: ftp://turing.imag.fr/pub/compression/ (1994-09-22) + + Original name: codhuff.c + + Changes: I/O to char arrays instead of file i/o. + Dynamic memory allocation replaced by array. + Explicit sorting algorithm. + + License: + +The source code files (codrl1.c, dcodrl1.c, codrle2.c, dcodrle2.c, codrle3.c, +dcodrle3.c, codrle4.c, dcodrle4.c, codhuff.c, dcodhuff.c) are copyrighted. +They have been uploaded on ftp in turing.imag.fr (129.88.31.7):/pub/compression +on 22/5/94 and have been modified on 22/9/94. +(c) David Bourgin - 1994 +The source codes I provide have no buggs (!) but being that I make them +available for free I have some notes to make. They can change at any time +without notice. I assume no responsability or liability for any errors or +inaccurracies, make no warranty of any kind (express, implied or statutory) +with respect to this publication and expressly disclaim any and all warranties +of merchantability, fitness for particular purposes. Of course, if you have +some problems to use the information presented here, I will try to help you if +I can. + +If you include the source codes in your application, here are the conditions: +- You have to put my name in the header of your source file (not in the +excutable program if you don't want) (this item is a must) +- I would like to see your resulting application, if possible (this item is not +a must, because some applications must remain secret) +- Whenever you gain money with your application, I would like to receive a very +little part in order to be encouraged to update my source codes and to develop +new schemes (this item is not a must) + +*/ + + +/* + Declaration of types +*/ + + +#include "../extra.h" +typedef struct huff_enc_s_tree { + unsigned int byte; /* A byte has to be coded as an unsigned integer to + allow a node to have a value over 255 */ + unsigned long int weight; + struct huff_enc_s_tree *left_ptr; + struct huff_enc_s_tree *right_ptr; +} huff_enc_t_tree; + +typedef struct { + unsigned char bits[32]; + unsigned int bits_nb; +} huff_enc_t_bin_val; + + +/* + Forward declaration of functions +*/ + +void huff_enc_init( void ); +int huff_enc_return( void ); +void huff_enc_beginning_of_data(); +int huff_enc_end_of_data(); +int huff_enc_read_byte(); +void huff_enc_write_byte( char ch ); +void huff_enc_write_bin_val( huff_enc_t_bin_val bin_val ); +void huff_enc_fill_encoding( void ); +void huff_enc_write_header( huff_enc_t_bin_val codes_table[257] ); +int huff_enc_weighhuff_enc_t_tree_comp( const void *t1, const void *t2 ); +void huff_enc_swapi( char *ii, char *ij, unsigned long es ); +char *huff_enc_pivot( char *a, unsigned long n, unsigned long es ); +void huff_enc_qsort( char *a, unsigned long n, unsigned long es ); +huff_enc_t_tree *huff_enc_build_tree_encoding( huff_enc_t_tree heap[514] ); +void huff_enc_encode_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257], huff_enc_t_bin_val *code_val ); +void huff_enc_create_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257] ); +void huff_enc_main(); +//int main( void ); + + +/* + Declaration of global variables +*/ + +static int huff_enc_input_pos; +static int huff_enc_output_pos; +static unsigned char huff_enc_output[1024]; +static unsigned char huff_enc_byte_nb_to_write = 0; +static unsigned char huff_enc_val_to_write = 0; + + +/* + Initialization- and return-value-related functions +*/ + +#define huff_enc_plaintext_len 600 +static const char *huff_enc_plaintext = + "You are doubtless asking \"How can I reduce the data size without losing " + "some informations?\". It's easy to answer to this question. I'll only take " + "an example. I'm sure you have heard about the morse. This system established " + "in the 19th century use a scheme very close to the huffman one. In the morse " + "you encode the letters to transmit with two kinds of signs. If you encode " + "these two sign possibilities in one bit, the symbol 'e' is transmitted in a " + "single bit and the symbols 'y' and 'z' need four bits. Look at the symbols " + "in the text you are reading, you'll fast understand the compression ratio..."; + +#define huff_enc_encoded_len 419 +static unsigned char huff_enc_encoded[huff_enc_encoded_len] = { + 128, 0, 0, 0, 80, 133, 32, 32, 128, 100, 4, 32, 63, 239, 255, 240, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 7, 167, 21, 129, 232, 69, 120, 132, 217, 20, 162, 19, 164, 39, 133, + 252, 138, 105, 20, 194, 19, 129, 240, 172, 138, 248, 150, 11, 11, 240, 201, + 68, 64, 114, 53, 17, 42, 37, 195, 128, 212, 116, 194, 41, 98, 52, 51, + 12, 132, 112, 244, 3, 36, 33, 52, 39, 135, 164, 33, 62, 156, 87, 14, + 110, 22, 87, 50, 85, 198, 99, 142, 140, 194, 81, 78, 158, 84, 129, 254, + 129, 248, 110, 179, 159, 192, 145, 133, 184, 184, 28, 210, 96, 146, 73, 10, + 226, 21, 83, 152, 74, 13, 111, 132, 199, 202, 219, 241, 74, 193, 167, 105, + 222, 31, 147, 6, 55, 31, 129, 40, 232, 52, 153, 160, 148, 18, 36, 197, + 45, 216, 202, 86, 30, 31, 177, 90, 133, 138, 248, 23, 81, 195, 160, 100, + 215, 93, 50, 185, 225, 251, 23, 6, 230, 225, 229, 112, 71, 80, 96, 141, + 205, 176, 230, 85, 196, 9, 24, 93, 90, 121, 225, 76, 68, 152, 63, 25, + 107, 140, 101, 204, 214, 77, 26, 194, 96, 18, 48, 77, 210, 137, 1, 253, + 4, 230, 248, 56, 240, 224, 111, 163, 95, 10, 12, 223, 7, 234, 167, 129, + 40, 36, 96, 135, 125, 245, 250, 2, 198, 120, 127, 0, 145, 133, 213, 167, + 135, 149, 195, 67, 235, 108, 9, 24, 87, 17, 102, 152, 37, 4, 222, 131, + 188, 144, 73, 36, 128, 73, 20, 81, 152, 177, 133, 248, 28, 165, 131, 120, + 127, 240, 242, 184, 104, 125, 109, 129, 35, 30, 4, 145, 65, 202, 88, 9, + 138, 103, 44, 205, 100, 167, 24, 152, 11, 24, 51, 37, 66, 9, 24, 31, + 174, 202, 212, 49, 152, 18, 96, 155, 208, 119, 146, 45, 97, 48, 56, 28, + 194, 90, 224, 204, 144, 232, 176, 36, 96, 126, 187, 43, 83, 12, 121, 129, + 209, 96, 197, 35, 2, 54, 176, 249, 92, 208, 204, 145, 188, 41, 170, 180, + 71, 16, 36, 96, 126, 187, 43, 83, 19, 0, 145, 129, 100, 209, 15, 43, + 135, 55, 6, 238, 180, 194, 90, 17, 229, 115, 21, 168, 251, 140, 131, 162, + 217, 166, 93, 22, 4, 140, 31, 91, 166, 55, 25, 202, 192, 111, 20, 171, + 207, 39, 192, +}; + + +void huff_enc_init( void ) +{ + huff_enc_input_pos = 0; + huff_enc_output_pos = 0; +} + + +int huff_enc_return( void ) +{ + int i; + _Pragma( "loopbound min 1 max 419" ) + for ( i = 0; i < huff_enc_encoded_len; i++ ) { + if ( huff_enc_encoded[i] != huff_enc_output[i] ) return i + 1; + } + return 0; +} + + +/* + Input / output functions +*/ + +void huff_enc_beginning_of_data() +{ + huff_enc_input_pos = 0; +} + + +int huff_enc_end_of_data() +{ + return huff_enc_input_pos >= huff_enc_plaintext_len; +} + + +int huff_enc_read_byte() +{ + return huff_enc_plaintext[huff_enc_input_pos++]; +} + + +void huff_enc_write_byte( char ch ) +{ + huff_enc_output[huff_enc_output_pos++] = ch; +} + + +void huff_enc_write_bin_val( huff_enc_t_bin_val bin_val ) +/* Returned parameters: None + Action: Writes in the output stream the value binary-coded into 'bin_val' + Errors: An input/output error could disturb the running of the program +*/ +{ + unsigned char bit_indice; + unsigned char bin_pos = ( bin_val.bits_nb - 1 ) & 7; + unsigned int pos_byte = ( bin_val.bits_nb - 1 ) >> 3; + + for ( bit_indice = 1; + bit_indice <= bin_val.bits_nb; + bit_indice++ ) { + /* Watch for the current bit to write */ + huff_enc_val_to_write = ( huff_enc_val_to_write << 1 ) | + ( ( bin_val.bits[pos_byte] >> bin_pos ) & 1 ); + /* Move to the next bit to write */ + if ( !bin_pos ) { + pos_byte--; + bin_pos = 7; + } else bin_pos--; + if ( huff_enc_byte_nb_to_write == 7 ) { + /* Are already 8 bits written? */ + huff_enc_write_byte( huff_enc_val_to_write ); + huff_enc_byte_nb_to_write = 0; + huff_enc_val_to_write = 0; + } else /* No, then the next writting will be in the next bit */ + huff_enc_byte_nb_to_write++; + } +} + + +void huff_enc_fill_encoding( void ) +/* Returned parameters: None + Action: Fills the last byte to write in the output stream with zero values + Errors: An input/output error could disturb the running of the program +*/ +{ + if ( huff_enc_byte_nb_to_write ) + huff_enc_write_byte( huff_enc_val_to_write << + ( 8 - huff_enc_byte_nb_to_write ) ); +} + + +void huff_enc_write_header( huff_enc_t_bin_val codes_table[257] ) +/* Returned parameters: None + Action: Writes the header in the stream of codes + Errors: An input/output error could disturb the running of the program +*/ +{ + unsigned int i, j; + huff_enc_t_bin_val bin_val_to_0; + huff_enc_t_bin_val bin_val_to_1; + huff_enc_t_bin_val bin_val; + /* Is used to send in binary mode via huff_enc_write_bin_val */ + + *bin_val_to_0.bits = 0; + bin_val_to_0.bits_nb = 1; + *bin_val_to_1.bits = 1; + bin_val_to_1.bits_nb = 1; + for ( i = 0, j = 0; j <= 255; j++ ) + if ( codes_table[j].bits_nb ) i++; + /* From there, i contains the number of bytes of the several + non 0 occurrences to encode. + First part of the header: Specifies the bytes that appear + in the source of encoding */ + if ( i < 32 ) { + /* Encoding of the appeared bytes with a block of bytes */ + huff_enc_write_bin_val( bin_val_to_0 ); + bin_val.bits_nb = 5; + *bin_val.bits = ( unsigned char )( i - 1 ); + huff_enc_write_bin_val( bin_val ); + bin_val.bits_nb = 8; + for ( j = 0; j <= 255; j++ ) + if ( codes_table[j].bits_nb ) { + *bin_val.bits = ( unsigned char )j; + huff_enc_write_bin_val( bin_val ); + } + } else { + /* Encoding of the appeared bytes with a block of bits */ + huff_enc_write_bin_val( bin_val_to_1 ); + for ( j = 0; j <= 255; j++ ) + if ( codes_table[j].bits_nb ) + huff_enc_write_bin_val( bin_val_to_1 ); + else huff_enc_write_bin_val( bin_val_to_0 ); + }; + /* Second part of the header: Specifies the encoding of the bytes + (fictive or not) that appear in the source of encoding */ + for ( i = 0; i <= 256; i++ ) + if ( ( j = codes_table[i].bits_nb ) != 0 ) { + if ( j < 33 ) { + huff_enc_write_bin_val( bin_val_to_0 ); + bin_val.bits_nb = 5; + } else { + huff_enc_write_bin_val( bin_val_to_1 ); + bin_val.bits_nb = 8; + } + *bin_val.bits = ( unsigned char )( j - 1 ); + huff_enc_write_bin_val( bin_val ); + huff_enc_write_bin_val( codes_table[i] ); + } +} + + +int huff_enc_weighhuff_enc_t_tree_comp( const void *t1, const void *t2 ) +/* Returned parameters: Returns a comparison status + Action: Returns a negative, zero or positive integer depending on the weight + of 'tree2' is less than, equal to, or greater than the weight of + 'tree1' + Errors: None +*/ +{ + huff_enc_t_tree *const *tree1 = ( huff_enc_t_tree *const * ) t1; + huff_enc_t_tree *const *tree2 = ( huff_enc_t_tree *const * ) t2; + return ( ( *tree2 )->weight ^ ( *tree1 )->weight ) + ? ( ( ( *tree2 )->weight < ( *tree1 )->weight ) ? -1 : 1 ) : 0; +} + + +void huff_enc_swapi( char *ii, char *ij, unsigned long es ) +{ + char *i, *j, c; + + i = ( char * )ii; + j = ( char * )ij; + _Pragma( "loopbound min 4 max 4" ) + do { + c = *i; + *i++ = *j; + *j++ = c; + es -= sizeof( char ); + } while ( es != 0 ); +} + + +char *huff_enc_pivot( char *a, unsigned long n, unsigned long es ) +{ + long j; + char *pi, *pj, *pk; + + j = n / 6 * es; + pi = a + j; /* 1/6 */ + j += j; + pj = pi + j; /* 1/2 */ + pk = pj + j; /* 5/6 */ + if ( huff_enc_weighhuff_enc_t_tree_comp( pi, pj ) < 0 ) { + if ( huff_enc_weighhuff_enc_t_tree_comp( pi, pk ) < 0 ) { + if ( huff_enc_weighhuff_enc_t_tree_comp( pj, pk ) < 0 ) + return pj; + return pk; + } + return pi; + } + if ( huff_enc_weighhuff_enc_t_tree_comp( pj, pk ) < 0 ) { + if ( huff_enc_weighhuff_enc_t_tree_comp( pi, pk ) < 0 ) + return pi; + return pk; + } + return pj; +} + + +void huff_enc_qsort( char *a, unsigned long n, unsigned long es ) +{ + unsigned long j; + char *pi, *pj, *pn; + unsigned int flowfactdummy = 0; + + _Pragma( "loopbound min 0 max 8" ) + while ( n > 1 ) { + if ( n > 10 ) { + pi = huff_enc_pivot( a, n, es ); + } else { + pi = a + ( n >> 1 ) * es; + } + + huff_enc_swapi( a, pi, es ); + pi = a; + pn = a + n * es; + pj = pn; + _Pragma( "loopbound min 1 max 110" ) + while ( 1 ) { + /* wcc note: this assignment expression was added to avoid assignment of + * multiple loop bound annotations to same loop (cf. Ticket #0002323). */ + flowfactdummy++; + _Pragma( "loopbound min 1 max 19" ) + do { + pi += es; + } while ( pi < pn && huff_enc_weighhuff_enc_t_tree_comp( pi, a ) < 0 ); + _Pragma( "loopbound min 1 max 25" ) + do { + pj -= es; + } while ( pj > a && huff_enc_weighhuff_enc_t_tree_comp( pj, a ) > 0 ); + if ( pj < pi ) + break; + huff_enc_swapi( pi, pj, es ); + } + huff_enc_swapi( a, pj, es ); + j = ( pj - a ) / es; + + n = n - j - 1; + if ( j >= n ) { + huff_enc_qsort( a, j, es ); + a += ( j + 1 ) * es; + } else { + huff_enc_qsort( a + ( j + 1 )*es, n, es ); + n = j; + } + } +} + + +huff_enc_t_tree *huff_enc_build_tree_encoding( huff_enc_t_tree heap[514] ) +/* Returned parameters: Returns a tree of encoding + Action: Generates an Huffman encoding tree based on the data from + the stream to compress + Errors: None +*/ +{ + unsigned int i; + unsigned int heap_top = 0; + huff_enc_t_tree *occurrences_table[257]; + huff_enc_t_tree *ptr_fictive_tree; + + /* Sets up the occurrences number of all bytes to 0 */ + for ( i = 0; i <= 256; i++ ) { + occurrences_table[i] = &heap[heap_top++]; + occurrences_table[i]->byte = i; + occurrences_table[i]->weight = 0; + occurrences_table[i]->left_ptr = 0; + occurrences_table[i]->right_ptr = 0; + } + /* Valids the occurrences of 'occurrences_table' with regard to the data to + compress */ + if ( !huff_enc_end_of_data() ) { + while ( !huff_enc_end_of_data() ) { + i = huff_enc_read_byte(); + occurrences_table[i]->weight++; + } + occurrences_table[256]->weight = 1; + + /* Sorts the occurrences table depending on the weight of each character */ + huff_enc_qsort( ( char * )occurrences_table, 257, sizeof( huff_enc_t_tree * ) ); + + for ( i = 256; ( i != 0 ) && ( !occurrences_table[i]->weight ); i-- ) + ; + i++; + /* From there, 'i' gives the number of different bytes with a 0 occurrence + in the stream to compress */ + while ( i > 0 ) { + /* Looks up (i+1)/2 times the occurrence table to link the nodes in an + unique tree */ + ptr_fictive_tree = &heap[heap_top++]; + ptr_fictive_tree->byte = 257; + ptr_fictive_tree->weight = occurrences_table[--i]->weight; + ptr_fictive_tree->left_ptr = occurrences_table[i]; + if ( i ) { + i--; + ptr_fictive_tree->weight += occurrences_table[i]->weight; + ptr_fictive_tree->right_ptr = occurrences_table[i]; + } else ptr_fictive_tree->right_ptr = 0; + occurrences_table[i] = ptr_fictive_tree; + + //qsort( ( char * )occurrences_table, i + 1, sizeof( *huff_enc_t_tree ), + //huff_enc_weighhuff_enc_t_tree_comp ); + huff_enc_qsort( ( char * )occurrences_table, i + 1, + sizeof( huff_enc_t_tree * ) ); + + if ( i ) /* Is there an other node in the occurrence tables? */ + i++; /* Yes, then takes care to the fictive node */ + } + } + return ( *occurrences_table ); +} + + +void huff_enc_encode_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257], + huff_enc_t_bin_val *code_val ) +/* Returned parameters: The data of 'codes_table' can have been modified + Action: Stores the encoding tree as a binary encoding table to speed up the + access. 'val_code' gives the encoding for the current node of the tree + Errors: None +*/ +{ + unsigned int i; + huff_enc_t_bin_val tmp_code_val; + + if ( tree->byte == 257 ) { + if ( tree->left_ptr != 0 ) + /* The sub-trees on left begin with an bit set to 1 */ + { + tmp_code_val = *code_val; + for ( i = 31; i > 0; i-- ) + code_val->bits[i] = ( code_val->bits[i] << 1 ) | + ( code_val->bits[i - 1] >> 7 ); + *code_val->bits = ( *code_val->bits << 1 ) | 1; + code_val->bits_nb++; + huff_enc_encode_codes_table( tree->left_ptr, codes_table, code_val ); + *code_val = tmp_code_val; + }; + if ( tree->right_ptr != 0 ) + /* The sub-trees on right begin with an bit set to 0 */ + { + tmp_code_val = *code_val; + for ( i = 31; i > 0; i-- ) + code_val->bits[i] = ( code_val->bits[i] << 1 ) | + ( code_val->bits[i - 1] >> 7 ); + *code_val->bits <<= 1; + code_val->bits_nb++; + huff_enc_encode_codes_table( tree->right_ptr, codes_table, code_val ); + *code_val = tmp_code_val; + }; + } else codes_table[tree->byte] = *code_val; +} + + +void huff_enc_create_codes_table( huff_enc_t_tree *tree, + huff_enc_t_bin_val codes_table[257] ) +/* Returned parameters: The data in 'codes_table' will be modified + Action: Stores the encoding tree as a binary encoding table to speed up + the access by calling encode_codes_table + Errors: None +*/ +{ + unsigned int i, j; + huff_enc_t_bin_val code_val; + + _Pragma( "loopbound min 32 max 32" ) + for ( i = 0; i < 32; i++ ) { + code_val.bits[i] = 0; + } + code_val.bits_nb = 0; + _Pragma( "loopbound min 257 max 257" ) + for ( j = 0; j < 257; j++ ) { + _Pragma( "loopbound min 32 max 32" ) + for ( i = 0; i < 32; i++ ) { + codes_table[j].bits[i] = 0; + } + codes_table[j].bits_nb = 0; + } + _Pragma( "marker call_encode" ) + _Pragma( "flowrestriction 1*huff_enc_encode_codes_table <= 77*call_encode" ) + huff_enc_encode_codes_table( tree, codes_table, &code_val ); +} + + +void _Pragma( "entrypoint" ) huff_enc_main() +/* Returned parameters: None + Action: Compresses with Huffman method all bytes read by the function + 'huff_enc_read_byte' + Errors: None +*/ +{ + huff_enc_t_tree *tree; + huff_enc_t_tree heap[514]; + huff_enc_t_bin_val encoding_table[257]; + unsigned char byte_read; + + if ( !huff_enc_end_of_data() ) { + /* Generates only whether there are data */ + tree = huff_enc_build_tree_encoding( heap ); + /* Creation of the best adapted tree */ + huff_enc_create_codes_table( tree, encoding_table ); + /* Obtains the binary encoding in an array to speed up the accesses */ + huff_enc_write_header( encoding_table ); + /* Writes the defintion of the encoding */ + huff_enc_beginning_of_data(); /* Real compression of the data */ + while ( !huff_enc_end_of_data() ) { + byte_read = huff_enc_read_byte(); + huff_enc_write_bin_val( encoding_table[byte_read] ); + } + huff_enc_write_bin_val( encoding_table[256] ); + /* Code of the end of encoding */ + huff_enc_fill_encoding(); + /* Fills the last byte before closing file, if any */ + } +} + + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete +#include +#include +#include +#include +#include +#include +#include <../litmus.h> + +#define L3_CACHE_SIZE (11264*1024) + +#define SAVE_RESULTS if(jobsComplete>-1) progTime[jobsComplete]=(end.tv_nsec-start.tv_nsec)+(1000000000*(end.tv_sec-start.tv_sec)); + + +#define SET_UP char *thisProgram=argv[1];\ + int maxJobs=atoi(argv[2]);\ + char *thisCore=argv[3];\ + char *otherCore=argv[4];\ + char *otherProgram=argv[5];\ + char *runID=argv[6];\ + int output=atoi(argv[7]);\ + struct timespec start, end;\ + int jobsComplete;\ + long progTime[maxJobs*output];\ + char fileName[50];\ + char *bigArray;\ + strcpy(fileName, runID);\ + strcat(fileName, ".txt");\ + mlockall(MCL_CURRENT || MCL_FUTURE); + +#define WRITE_TO_FILE if (output){\ + munlockall();\ + FILE *fp=fopen(fileName, "a");\ + for(jobsComplete=0; jobsComplete + mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD + MV[][][]: motion vectors (frame format) + mv_field_sel: top/bottom field (for field prediction) + motion_type: MC_FRAME, MC_FIELD + + uses global vars: mpeg2_pict_type, frame_pred_dct +*/ +void mpeg2_motion_estimation( unsigned char *oldorg, unsigned char *neworg, + unsigned char *oldref, unsigned char *newref, + unsigned char *cur, unsigned char *curref, + int sxf, int syf, int sxb, int syb, + struct mbinfo *mbi, int secondfield, int ipflag ) +{ + int i, j; + + + /* loop through all macroblocks of the picture */ + _Pragma( "loopbound min 16 max 16" ) + for ( j = 0; j < mpeg2_height2; j += 16 ) { + i = 0; + _Pragma( "loopbound min 22 max 22" ) + for ( ; i < mpeg2_width; i += 16 ) { + if ( mpeg2_pict_struct == 3 ) + mpeg2_frame_ME( + oldorg, neworg, oldref, newref, cur, i, j, sxf, syf, sxb, syb, mbi ); + else + mpeg2_field_ME( + oldorg, neworg, oldref, newref, cur, curref, i, j, sxf, syf, sxb, syb, + mbi, secondfield, ipflag ); + mbi++; + } + } +} + + +void mpeg2_frame_ME( unsigned char *oldorg, unsigned char *neworg, + unsigned char *oldref, unsigned char *newref, + unsigned char *cur, int i, int j, int sxf, int syf, + int sxb, int syb, struct mbinfo *mbi ) +{ + int imin, jmin, iminf, jminf, iminr, jminr; + int imint, jmint, iminb, jminb; + int imintf, jmintf, iminbf, jminbf; + int imintr, jmintr, iminbr, jminbr; + int var, v0; + int dmc, dmcf, dmcr, dmci, vmc, vmcf, vmcr, vmci; + int dmcfield, dmcfieldf, dmcfieldr, dmcfieldi; + int tsel, bsel, tself, bself, tselr, bselr; + unsigned char *mb; + int imins[ 2 ][ 2 ], jmins[ 2 ][ 2 ]; + int imindp, jmindp, imindmv, jmindmv, dmc_dp, vmc_dp; + + + mb = cur + i + mpeg2_width * j; + + var = mpeg2_variance( mb, mpeg2_width ); + + if ( mpeg2_pict_type == 1 ) + mbi->mb_type = 1; + else + + if ( mpeg2_pict_type == 2 ) { + if ( mpeg2_frame_pred_dct ) { + dmc = + mpeg2_fullsearch( + oldorg, oldref, mb, mpeg2_width, i, j, sxf, syf, 16, mpeg2_width, + mpeg2_height, &imin, &jmin ); + vmc = + mpeg2_dist2( + oldref + ( imin >> 1 ) + mpeg2_width * ( jmin >> 1 ), mb, mpeg2_width, + imin & 1, jmin & 1, 16 ); + mbi->motion_type = 2; + } else { + mpeg2_frame_estimate( + oldorg, oldref, mb, i, j, sxf, syf, &imin, &jmin, &imint, &jmint, + &iminb, &jminb, &dmc, &dmcfield, &tsel, &bsel, imins, jmins ); + + if ( mpeg2_M == 1 ) + mpeg2_dpframe_estimate( + oldref, mb, i, j >> 1, imins, jmins, &imindp, &jmindp, &imindmv, + &jmindmv, &dmc_dp, &vmc_dp ); + + /* select between dual prime, frame and field prediction */ + if ( ( mpeg2_M == 1 ) && ( dmc_dp < dmc ) && ( dmc_dp < dmcfield ) ) { + mbi->motion_type = 3; + dmc = dmc_dp; + vmc = vmc_dp; + } else + + if ( dmc <= dmcfield ) { + mbi->motion_type = 2; + vmc = + mpeg2_dist2( + oldref + ( imin >> 1 ) + mpeg2_width * ( jmin >> 1 ), mb, + mpeg2_width, imin & 1, jmin & 1, 16 ); + } else { + mbi->motion_type = 1; + dmc = dmcfield; + vmc = + mpeg2_dist2( + oldref + ( tsel ? mpeg2_width : 0 ) + ( imint >> 1 ) + + ( mpeg2_width << 1 ) * ( jmint >> 1 ), + mb, mpeg2_width << 1, imint & 1, jmint & 1, 8 ); + vmc += + mpeg2_dist2( + oldref + ( bsel ? mpeg2_width : 0 ) + ( iminb >> 1 ) + + ( mpeg2_width << 1 ) * ( jminb >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminb & 1, jminb & 1, 8 ); + } + } + + /* + select between intra or non-intra coding: + + selection is based on intra block variance (var) vs. + prediction error variance (vmc) + + blocks with small prediction error are always coded non-intra + even if variance is smaller (is this reasonable?) + */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + /* + select between MC / No-MC + + use No-MC if var(No-MC) <= 1.25*var(MC) + (i.e slightly biased towards No-MC) + + blocks with small prediction error are always coded as No-MC + (requires no motion vectors, allows skipping) + */ + v0 = + mpeg2_dist2( oldref + i + mpeg2_width * j, mb, mpeg2_width, 0, 0, 16 ); + + if ( ( 4 * v0 > 5 * vmc ) && ( v0 >= 9 * 256 ) ) { + /* use MC */ + var = vmc; + mbi->mb_type = 8; + + if ( mbi->motion_type == 2 ) { + mbi->MV[ 0 ][ 0 ][ 0 ] = imin - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin - ( j << 1 ); + } else + + if ( mbi->motion_type == 3 ) { + /* these are FRAME vectors */ + /* same parity vector */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imindp - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = ( jmindp << 1 ) - ( j << 1 ); + + /* opposite parity vector */ + mbi->dmvector[ 0 ] = imindmv; + mbi->dmvector[ 1 ] = jmindmv; + } else { + /* these are FRAME vectors */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imint - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = ( jmint << 1 ) - ( j << 1 ); + mbi->MV[ 1 ][ 0 ][ 0 ] = iminb - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = ( jminb << 1 ) - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = tsel; + mbi->mv_field_sel[ 1 ][ 0 ] = bsel; + } + } else { + /* No-MC */ + var = v0; + mbi->mb_type = 0; + mbi->motion_type = 2; + mbi->MV[ 0 ][ 0 ][ 0 ] = 0; + mbi->MV[ 0 ][ 0 ][ 1 ] = 0; + } + } + } else { /* if (mpeg2_pict_type==B_TYPE) */ + + if ( mpeg2_frame_pred_dct ) { + /* forward */ + dmcf = + mpeg2_fullsearch( + oldorg, oldref, mb, mpeg2_width, i, j, sxf, syf, 16, mpeg2_width, + mpeg2_height, &iminf, &jminf ); + vmcf = + mpeg2_dist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), mb, + mpeg2_width, iminf & 1, jminf & 1, 16 ); + + /* backward */ + dmcr = + mpeg2_fullsearch( + neworg, newref, mb, mpeg2_width, i, j, sxb, syb, 16, mpeg2_width, + mpeg2_height, &iminr, &jminr ); + vmcr = + mpeg2_dist2( + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), mb, + mpeg2_width, iminr & 1, jminr & 1, 16 ); + + /* interpolated (bidirectional) */ + vmci = + mpeg2_bdist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), + mb, mpeg2_width, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + + /* decisions */ + + /* + select between forward/backward/interpolated prediction: + use the one with smallest mean sqaured prediction error + */ + if ( ( vmcf <= vmcr ) && ( vmcf <= vmci ) ) { + vmc = vmcf; + mbi->mb_type = 8; + } else + + if ( vmcr <= vmci ) { + vmc = vmcr; + mbi->mb_type = 4; + } else { + vmc = vmci; + mbi->mb_type = 8 | 4; + } + + mbi->motion_type = 2; + } else { + /* forward prediction */ + mpeg2_frame_estimate( + oldorg, oldref, mb, i, j, sxf, syf, &iminf, &jminf, &imintf, &jmintf, + &iminbf, &jminbf, &dmcf, &dmcfieldf, &tself, &bself, imins, jmins ); + + /* backward prediction */ + mpeg2_frame_estimate( + neworg, newref, mb, i, j, sxb, syb, &iminr, &jminr, &imintr, &jmintr, + &iminbr, &jminbr, &dmcr, &dmcfieldr, &tselr, &bselr, imins, jmins ); + + /* calculate interpolated distance */ + /* frame */ + dmci = + mpeg2_bdist1( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), + mb, mpeg2_width, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + + /* top field */ + dmcfieldi = + mpeg2_bdist1( + oldref + ( imintf >> 1 ) + ( tself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintf >> 1 ), + newref + ( imintr >> 1 ) + ( tselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintr >> 1 ), + mb, mpeg2_width << 1, imintf & 1, jmintf & 1, imintr & 1, jmintr & 1, + 8 ); + + /* bottom field */ + dmcfieldi += + mpeg2_bdist1( + oldref + ( iminbf >> 1 ) + ( bself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbf >> 1 ), + newref + ( iminbr >> 1 ) + ( bselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbr >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbf & 1, jminbf & 1, iminbr & 1, + jminbr & 1, 8 ); + + /* + select prediction type of minimum distance from the + six candidates (field/frame * forward/backward/interpolated) + */ + if ( ( dmci < dmcfieldi ) && ( dmci < dmcf ) && ( dmci < dmcfieldf ) && + ( dmci < dmcr ) && ( dmci < dmcfieldr ) ) { + /* frame, interpolated */ + mbi->mb_type = 8 | 4; + mbi->motion_type = 2; + vmc = + mpeg2_bdist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), + mb, mpeg2_width, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + } else + + if ( ( dmcfieldi < dmcf ) && ( dmcfieldi < dmcfieldf ) && + ( dmcfieldi < dmcr ) && ( dmcfieldi < dmcfieldr ) ) { + /* field, interpolated */ + mbi->mb_type = 8 | 4; + mbi->motion_type = 1; + vmc = + mpeg2_bdist2( + oldref + ( imintf >> 1 ) + ( tself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintf >> 1 ), + newref + ( imintr >> 1 ) + ( tselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jmintr >> 1 ), + mb, mpeg2_width << 1, imintf & 1, jmintf & 1, imintr & 1, jmintr & 1, + 8 ); + vmc += + mpeg2_bdist2( + oldref + ( iminbf >> 1 ) + ( bself ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbf >> 1 ), + newref + ( iminbr >> 1 ) + ( bselr ? mpeg2_width : 0 ) + + ( mpeg2_width << 1 ) * ( jminbr >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbf & 1, jminbf & 1, + iminbr & 1, jminbr & 1, 8 ); + } else + + if ( ( dmcf < dmcfieldf ) && ( dmcf < dmcr ) && ( dmcf < dmcfieldr ) ) { + /* frame, forward */ + mbi->mb_type = 8; + mbi->motion_type = 2; + vmc = + mpeg2_dist2( + oldref + ( iminf >> 1 ) + mpeg2_width * ( jminf >> 1 ), mb, + mpeg2_width, iminf & 1, jminf & 1, 16 ); + } else + + if ( ( dmcfieldf < dmcr ) && ( dmcfieldf < dmcfieldr ) ) { + /* field, forward */ + mbi->mb_type = 8; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + oldref + ( tself ? mpeg2_width : 0 ) + ( imintf >> 1 ) + + ( mpeg2_width << 1 ) * ( jmintf >> 1 ), + mb, mpeg2_width << 1, imintf & 1, jmintf & 1, 8 ); + vmc += + mpeg2_dist2( + oldref + ( bself ? mpeg2_width : 0 ) + ( iminbf >> 1 ) + + ( mpeg2_width << 1 ) * ( jminbf >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbf & 1, jminbf & 1, 8 ); + } else + + if ( dmcr < dmcfieldr ) { + /* frame, backward */ + mbi->mb_type = 4; + mbi->motion_type = 2; + vmc = + mpeg2_dist2( + newref + ( iminr >> 1 ) + mpeg2_width * ( jminr >> 1 ), mb, + mpeg2_width, iminr & 1, jminr & 1, 16 ); + } else { + /* field, backward */ + mbi->mb_type = 4; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + newref + ( tselr ? mpeg2_width : 0 ) + ( imintr >> 1 ) + + ( mpeg2_width << 1 ) * ( jmintr >> 1 ), + mb, mpeg2_width << 1, imintr & 1, jmintr & 1, 8 ); + vmc += + mpeg2_dist2( + newref + ( bselr ? mpeg2_width : 0 ) + ( iminbr >> 1 ) + + ( mpeg2_width << 1 ) * ( jminbr >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, iminbr & 1, jminbr & 1, 8 ); + } + } + + /* + select between intra or non-intra coding: + + selection is based on intra block variance (var) vs. + prediction error variance (vmc) + + blocks with small prediction error are always coded non-intra + even if variance is smaller (is this reasonable?) + */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + var = vmc; + + if ( mbi->motion_type == 2 ) { + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = iminf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jminf - ( j << 1 ); + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = iminr - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = jminr - ( j << 1 ); + } else { + /* these are FRAME vectors */ + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imintf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = ( jmintf << 1 ) - ( j << 1 ); + mbi->MV[ 1 ][ 0 ][ 0 ] = iminbf - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = ( jminbf << 1 ) - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = tself; + mbi->mv_field_sel[ 1 ][ 0 ] = bself; + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = imintr - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = ( jmintr << 1 ) - ( j << 1 ); + mbi->MV[ 1 ][ 1 ][ 0 ] = iminbr - ( i << 1 ); + mbi->MV[ 1 ][ 1 ][ 1 ] = ( jminbr << 1 ) - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 1 ] = tselr; + mbi->mv_field_sel[ 1 ][ 1 ] = bselr; + } + } + } + + mbi->var = var; +} + + +/* + motion estimation for field pictures + + oldorg: original frame for forward prediction (P and B frames) + neworg: original frame for backward prediction (B frames only) + oldref: reconstructed frame for forward prediction (P and B frames) + newref: reconstructed frame for backward prediction (B frames only) + cur: current original frame (the one for which the prediction is formed) + curref: current reconstructed frame (to predict second field from first) + sxf,syf: forward search window (frame coordinates) + sxb,syb: backward search window (frame coordinates) + mbi: pointer to macroblock info structure + secondfield: indicates second field of a frame (in P fields this means + that reference field of opposite parity is in curref instead + of oldref) + ipflag: indicates a P type field which is the second field of a frame + in which the first field is I type (this restricts predictions + to be based only on the opposite parity (=I) field) + + results: + mbi-> + mb_type: 0, MB_INTRA, MB_FORWARD, MB_BACKWARD, MB_FORWARD|MB_BACKWARD + MV[][][]: motion vectors (field format) + mv_field_sel: top/bottom field + motion_type: MC_FIELD, MC_16X8 + + uses global vars: mpeg2_pict_type, mpeg2_pict_struct +*/ +void mpeg2_field_ME( unsigned char *oldorg, unsigned char *neworg, + unsigned char *oldref, unsigned char *newref, + unsigned char *cur, unsigned char *curref, int i, int j, + int sxf, int syf, int sxb, int syb, struct mbinfo *mbi, + int secondfield, int ipflag ) +{ + int w2; + unsigned char *mb, *toporg, *topref, *botorg, *botref; + int var, vmc, v0, dmcfieldi, dmc8i; + int imin, jmin, imin8u, jmin8u, imin8l, jmin8l, dmcfield, dmc8, sel, sel8u, + sel8l; + int iminf, jminf, imin8uf, jmin8uf, imin8lf, jmin8lf, dmcfieldf, dmc8f, self, + sel8uf, sel8lf; + int iminr, jminr, imin8ur, jmin8ur, imin8lr, jmin8lr, dmcfieldr, dmc8r, selr, + sel8ur, sel8lr; + int imins, jmins, ds, imindmv, jmindmv, vmc_dp, dmc_dp; + + + w2 = mpeg2_width << 1; + mb = cur + i + w2 * j; + + if ( mpeg2_pict_struct == 2 ) + mb += mpeg2_width; + + var = mpeg2_variance( mb, w2 ); + + if ( mpeg2_pict_type == 1 ) + mbi->mb_type = 1; + else + + if ( mpeg2_pict_type == 2 ) { + toporg = oldorg; + topref = oldref; + botorg = oldorg + mpeg2_width; + botref = oldref + mpeg2_width; + + if ( secondfield ) { + /* opposite parity field is in same frame */ + if ( mpeg2_pict_struct == 1 ) { + /* current is top field */ + botorg = cur + mpeg2_width; + botref = curref + mpeg2_width; + } else { + /* current is bottom field */ + toporg = cur; + topref = curref; + } + } + + mpeg2_field_estimate( + toporg, topref, botorg, botref, mb, i, j, sxf, syf, ipflag, &imin, &jmin, + &imin8u, &jmin8u, &imin8l, &jmin8l, &dmcfield, &dmc8, &sel, &sel8u, + &sel8l, &imins, &jmins, &ds ); + + if ( ( mpeg2_M == 1 ) && !ipflag ) + /* generic condition which permits Dual Prime */ + mpeg2_dpfield_estimate( + topref, botref, mb, i, j, imins, jmins, &imindmv, &jmindmv, &dmc_dp, + &vmc_dp ); + + /* select between dual prime, field and 16x8 prediction */ + if ( ( mpeg2_M == 1 ) && !ipflag && ( dmc_dp < dmc8 ) && + ( dmc_dp < dmcfield ) ) { + /* Dual Prime prediction */ + mbi->motion_type = 3; + vmc = vmc_dp; /* we already calculated L2 error for Dual */ + + } else + + if ( dmc8 < dmcfield ) { + /* 16x8 prediction */ + mbi->motion_type = 2; + /* upper half block */ + vmc = + mpeg2_dist2( + ( sel8u ? botref : topref ) + ( imin8u >> 1 ) + w2 * ( jmin8u >> 1 ), + mb, w2, imin8u & 1, jmin8u & 1, 8 ); + /* lower half block */ + vmc += + mpeg2_dist2( + ( sel8l ? botref : topref ) + ( imin8l >> 1 ) + w2 * ( jmin8l >> 1 ), + mb + 8 * w2, w2, imin8l & 1, jmin8l & 1, 8 ); + } else { + /* field prediction */ + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + ( sel ? botref : topref ) + ( imin >> 1 ) + w2 * ( jmin >> 1 ), + mb, w2, imin & 1, jmin & 1, 16 ); + } + + /* select between intra and non-intra coding */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + /* + zero MV field prediction from same parity ref. field + (not allowed if ipflag is set) + */ + if ( !ipflag ) + v0 = + mpeg2_dist2( + ( ( mpeg2_pict_struct == 2 ) ? botref : topref ) + i + w2 * j, mb, + w2, 0, 0, 16 ); + + if ( ipflag || ( ( 4 * v0 > 5 * vmc ) && ( v0 >= 9 * 256 ) ) ) { + var = vmc; + mbi->mb_type = 8; + + if ( mbi->motion_type == 1 ) { + mbi->MV[ 0 ][ 0 ][ 0 ] = imin - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = sel; + } else + + if ( mbi->motion_type == 3 ) { + /* same parity vector */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imins - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmins - ( j << 1 ); + + /* opposite parity vector */ + mbi->dmvector[ 0 ] = imindmv; + mbi->dmvector[ 1 ] = jmindmv; + } else { + mbi->MV[ 0 ][ 0 ][ 0 ] = imin8u - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin8u - ( j << 1 ); + mbi->MV[ 1 ][ 0 ][ 0 ] = imin8l - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = jmin8l - ( ( j + 8 ) << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = sel8u; + mbi->mv_field_sel[ 1 ][ 0 ] = sel8l; + } + } else { + /* No MC */ + var = v0; + mbi->mb_type = 0; + mbi->motion_type = 1; + mbi->MV[ 0 ][ 0 ][ 0 ] = 0; + mbi->MV[ 0 ][ 0 ][ 1 ] = 0; + mbi->mv_field_sel[ 0 ][ 0 ] = ( mpeg2_pict_struct == 2 ); + } + } + } else { /* if (mpeg2_pict_type==B_TYPE) */ + /* forward prediction */ + mpeg2_field_estimate( + oldorg, oldref, oldorg + mpeg2_width, oldref + mpeg2_width, mb, i, j, sxf, + syf, 0, &iminf, &jminf, &imin8uf, &jmin8uf, &imin8lf, &jmin8lf, + &dmcfieldf, &dmc8f, &self, &sel8uf, &sel8lf, &imins, &jmins, &ds ); + + /* backward prediction */ + mpeg2_field_estimate( + neworg, newref, neworg + mpeg2_width, newref + mpeg2_width, mb, i, j, sxb, + syb, 0, &iminr, &jminr, &imin8ur, &jmin8ur, &imin8lr, &jmin8lr, + &dmcfieldr, &dmc8r, &selr, &sel8ur, &sel8lr, &imins, &jmins, &ds ); + + /* calculate distances for bidirectional prediction */ + /* field */ + dmcfieldi = + mpeg2_bdist1( + oldref + ( self ? mpeg2_width : 0 ) + ( iminf >> 1 ) + + w2 * ( jminf >> 1 ), + newref + ( selr ? mpeg2_width : 0 ) + ( iminr >> 1 ) + + w2 * ( jminr >> 1 ), + mb, w2, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + + /* 16x8 upper half block */ + dmc8i = + mpeg2_bdist1( + oldref + ( sel8uf ? mpeg2_width : 0 ) + ( imin8uf >> 1 ) + + w2 * ( jmin8uf >> 1 ), + newref + ( sel8ur ? mpeg2_width : 0 ) + ( imin8ur >> 1 ) + + w2 * ( jmin8ur >> 1 ), + mb, w2, imin8uf & 1, jmin8uf & 1, imin8ur & 1, jmin8ur & 1, 8 ); + + /* 16x8 lower half block */ + dmc8i += + mpeg2_bdist1( + oldref + ( sel8lf ? mpeg2_width : 0 ) + ( imin8lf >> 1 ) + + w2 * ( jmin8lf >> 1 ), + newref + ( sel8lr ? mpeg2_width : 0 ) + ( imin8lr >> 1 ) + + w2 * ( jmin8lr >> 1 ), + mb + 8 * w2, w2, imin8lf & 1, jmin8lf & 1, imin8lr & 1, jmin8lr & 1, + 8 ); + + /* select prediction type of minimum distance */ + if ( ( dmcfieldi < dmc8i ) && ( dmcfieldi < dmcfieldf ) && + ( dmcfieldi < dmc8f ) && ( dmcfieldi < dmcfieldr ) && + ( dmcfieldi < dmc8r ) ) { + /* field, interpolated */ + mbi->mb_type = 8 | 5; + mbi->motion_type = 1; + vmc = + mpeg2_bdist2( + oldref + ( self ? mpeg2_width : 0 ) + ( iminf >> 1 ) + + w2 * ( jminf >> 1 ), + newref + ( selr ? mpeg2_width : 0 ) + ( iminr >> 1 ) + + w2 * ( jminr >> 1 ), + mb, w2, iminf & 1, jminf & 1, iminr & 1, jminr & 1, 16 ); + } else + + if ( ( dmc8i < dmcfieldf ) && ( dmc8i < dmc8f ) && ( dmc8i < dmcfieldr ) && + ( dmc8i < dmc8r ) ) { + /* 16x8, interpolated */ + mbi->mb_type = 8 | 4; + mbi->motion_type = 2; + + /* upper half block */ + vmc = + mpeg2_bdist2( + oldref + ( sel8uf ? mpeg2_width : 0 ) + ( imin8uf >> 1 ) + + w2 * ( jmin8uf >> 1 ), + newref + ( sel8ur ? mpeg2_width : 0 ) + ( imin8ur >> 1 ) + + w2 * ( jmin8ur >> 1 ), + mb, w2, imin8uf & 1, jmin8uf & 1, imin8ur & 1, jmin8ur & 1, 8 ); + + /* lower half block */ + vmc += + mpeg2_bdist2( + oldref + ( sel8lf ? mpeg2_width : 0 ) + ( imin8lf >> 1 ) + + w2 * ( jmin8lf >> 1 ), + newref + ( sel8lr ? mpeg2_width : 0 ) + ( imin8lr >> 1 ) + + w2 * ( jmin8lr >> 1 ), + mb + 8 * w2, w2, imin8lf & 1, jmin8lf & 1, imin8lr & 1, jmin8lr & 1, + 8 ); + } else + + if ( ( dmcfieldf < dmc8f ) && ( dmcfieldf < dmcfieldr ) && + ( dmcfieldf < dmc8r ) ) { + /* field, forward */ + mbi->mb_type = 8; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + oldref + ( self ? mpeg2_width : 0 ) + ( iminf >> 1 ) + + w2 * ( jminf >> 1 ), + mb, w2, iminf & 1, jminf & 1, 16 ); + } else + + if ( ( dmc8f < dmcfieldr ) && ( dmc8f < dmc8r ) ) { + /* 16x8, forward */ + mbi->mb_type = 8; + mbi->motion_type = 2; + + /* upper half block */ + vmc = + mpeg2_dist2( + oldref + ( sel8uf ? mpeg2_width : 0 ) + ( imin8uf >> 1 ) + + w2 * ( jmin8uf >> 1 ), mb, w2, imin8uf & 1, jmin8uf & 1, 8 ); + + /* lower half block */ + vmc += + mpeg2_dist2( + oldref + ( sel8lf ? mpeg2_width : 0 ) + ( imin8lf >> 1 ) + + w2 * ( jmin8lf >> 1 ), + mb + 8 * w2, w2, imin8lf & 1, jmin8lf & 1, 8 ); + } else + + if ( dmcfieldr < dmc8r ) { + /* field, backward */ + mbi->mb_type = 4; + mbi->motion_type = 1; + vmc = + mpeg2_dist2( + newref + ( selr ? mpeg2_width : 0 ) + ( iminr >> 1 ) + + w2 * ( jminr >> 1 ), + mb, w2, iminr & 1, jminr & 1, 16 ); + } else { + /* 16x8, backward */ + mbi->mb_type = 4; + mbi->motion_type = 2; + + /* upper half block */ + vmc = + mpeg2_dist2( + newref + ( sel8ur ? mpeg2_width : 0 ) + ( imin8ur >> 1 ) + + w2 * ( jmin8ur >> 1 ), + mb, w2, imin8ur & 1, jmin8ur & 1, 8 ); + + /* lower half block */ + vmc += + mpeg2_dist2( + newref + ( sel8lr ? mpeg2_width : 0 ) + ( imin8lr >> 1 ) + + w2 * ( jmin8lr >> 1 ), + mb + 8 * w2, w2, imin8lr & 1, jmin8lr & 1, 8 ); + } + + /* select between intra and non-intra coding */ + if ( ( vmc > var ) && ( vmc >= 9 * 256 ) ) + mbi->mb_type = 1; + else { + var = vmc; + + if ( mbi->motion_type == 1 ) { + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = iminf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jminf - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = self; + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = iminr - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = jminr - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 1 ] = selr; + } else { /* MC_16X8 */ + /* forward */ + mbi->MV[ 0 ][ 0 ][ 0 ] = imin8uf - ( i << 1 ); + mbi->MV[ 0 ][ 0 ][ 1 ] = jmin8uf - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 0 ] = sel8uf; + mbi->MV[ 1 ][ 0 ][ 0 ] = imin8lf - ( i << 1 ); + mbi->MV[ 1 ][ 0 ][ 1 ] = jmin8lf - ( ( j + 8 ) << 1 ); + mbi->mv_field_sel[ 1 ][ 0 ] = sel8lf; + /* backward */ + mbi->MV[ 0 ][ 1 ][ 0 ] = imin8ur - ( i << 1 ); + mbi->MV[ 0 ][ 1 ][ 1 ] = jmin8ur - ( j << 1 ); + mbi->mv_field_sel[ 0 ][ 1 ] = sel8ur; + mbi->MV[ 1 ][ 1 ][ 0 ] = imin8lr - ( i << 1 ); + mbi->MV[ 1 ][ 1 ][ 1 ] = jmin8lr - ( ( j + 8 ) << 1 ); + mbi->mv_field_sel[ 1 ][ 1 ] = sel8lr; + } + } + } + + mbi->var = var; +} + + +/* + frame picture motion estimation + + org: top left pel of source reference frame + ref: top left pel of reconstructed reference frame + mb: macroblock to be matched + i,j: location of mb relative to ref (=center of search window) + sx,sy: half widths of search window + iminp,jminp,dframep: location and value of best frame prediction + imintp,jmintp,tselp: location of best field pred. for top field of mb + iminbp,jminbp,bselp: location of best field pred. for bottom field of mb + dfieldp: value of field prediction +*/ +void mpeg2_frame_estimate( unsigned char *org, unsigned char *ref, + unsigned char *mb, int i, int j, int sx, int sy, + int *iminp, int *jminp, int *imintp, int *jmintp, + int *iminbp, int *jminbp, int *dframep, int *dfieldp, + int *tselp, int *bselp, int imins[ 2 ][ 2 ], + int jmins[ 2 ][ 2 ] ) +{ + int dt, db, dmint, dminb; + int imint, iminb, jmint, jminb; + + + /* frame prediction */ + *dframep = + mpeg2_fullsearch( + org, ref, mb, mpeg2_width, i, j, sx, sy, 16, mpeg2_width, mpeg2_height, + iminp, jminp ); + + /* predict top field from top field */ + dt = + mpeg2_fullsearch( + org, ref, mb, mpeg2_width << 1, i, j>>1, sx, sy >> 1, 8, mpeg2_width, + mpeg2_height >> 1, &imint, &jmint ); + + /* predict top field from bottom field */ + db = + mpeg2_fullsearch( + org + mpeg2_width, ref + mpeg2_width, mb, mpeg2_width << 1, i, j>>1, sx, + sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &iminb, &jminb ); + + imins[ 0 ][ 0 ] = imint; + jmins[ 0 ][ 0 ] = jmint; + imins[ 1 ][ 0 ] = iminb; + jmins[ 1 ][ 0 ] = jminb; + + /* select prediction for top field */ + if ( dt <= db ) { + dmint = dt; + *imintp = imint; + *jmintp = jmint; + *tselp = 0; + } else { + dmint = db; + *imintp = iminb; + *jmintp = jminb; + *tselp = 1; + } + + /* predict bottom field from top field */ + dt = + mpeg2_fullsearch( + org, ref, mb + mpeg2_width, mpeg2_width << 1, i, j>>1, sx, sy >> 1, 8, + mpeg2_width, mpeg2_height >> 1, &imint, &jmint ); + + /* predict bottom field from bottom field */ + db = + mpeg2_fullsearch( + org + mpeg2_width, ref + mpeg2_width, mb + mpeg2_width, mpeg2_width << 1, + i, j>>1, sx, sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &iminb, &jminb ); + + imins[ 0 ][ 1 ] = imint; + jmins[ 0 ][ 1 ] = jmint; + imins[ 1 ][ 1 ] = iminb; + jmins[ 1 ][ 1 ] = jminb; + + /* select prediction for bottom field */ + if ( db <= dt ) { + dminb = db; + *iminbp = iminb; + *jminbp = jminb; + *bselp = 1; + } else { + dminb = dt; + *iminbp = imint; + *jminbp = jmint; + *bselp = 0; + } + + *dfieldp = dmint + dminb; +} + + +/* + field picture motion estimation subroutine + + toporg: address of original top reference field + topref: address of reconstructed top reference field + botorg: address of original bottom reference field + botref: address of reconstructed bottom reference field + mb: macroblock to be matched + i,j: location of mb (=center of search window) + sx,sy: half width/height of search window + + iminp,jminp,selp,dfieldp: location and distance of best field prediction + imin8up,jmin8up,sel8up: location of best 16x8 pred. for upper half of mb + imin8lp,jmin8lp,sel8lp: location of best 16x8 pred. for lower half of mb + d8p: distance of best 16x8 prediction + iminsp,jminsp,dsp: location and distance of best same parity field + prediction (needed for dual prime, only valid if + ipflag==0) +*/ +void mpeg2_field_estimate( unsigned char *toporg, unsigned char *topref, + unsigned char *botorg, unsigned char *botref, + unsigned char *mb, int i, int j, int sx, int sy, + int ipflag, int *iminp, int *jminp, int *imin8up, + int *jmin8up, int *imin8lp, int *jmin8lp, + int *dfieldp, int *d8p, int *selp, int *sel8up, + int *sel8lp, int *iminsp, int *jminsp, int *dsp ) +{ + int dt, db, imint, jmint, iminb, jminb, notop, nobot; + + + /* if ipflag is set, predict from field of opposite parity only */ + notop = ipflag && ( mpeg2_pict_struct == 1 ); + nobot = ipflag && ( mpeg2_pict_struct == 2 ); + + /* field prediction */ + + /* predict current field from top field */ + if ( notop ) + dt = 65536; /* infinity */ + else + dt = + mpeg2_fullsearch( + toporg, topref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 16, mpeg2_width, + mpeg2_height >> 1, &imint, &jmint ); + + /* predict current field from bottom field */ + if ( nobot ) + db = 65536; /* infinity */ + else + db = + mpeg2_fullsearch( + botorg, botref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 16, mpeg2_width, + mpeg2_height >> 1, &iminb, &jminb ); + + /* same parity prediction (only valid if ipflag==0) */ + if ( mpeg2_pict_struct == 1 ) { + *iminsp = imint; + *jminsp = jmint; + *dsp = dt; + } else { + *iminsp = iminb; + *jminsp = jminb; + *dsp = db; + } + + /* select field prediction */ + if ( dt <= db ) { + *dfieldp = dt; + *iminp = imint; + *jminp = jmint; + *selp = 0; + } else { + *dfieldp = db; + *iminp = iminb; + *jminp = jminb; + *selp = 1; + } + + + /* 16x8 motion compensation */ + + /* predict upper half field from top field */ + if ( notop ) + dt = 65536; + else + dt = + mpeg2_fullsearch( + toporg, topref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 8, mpeg2_width, + mpeg2_height >> 1, &imint, &jmint ); + + /* predict upper half field from bottom field */ + if ( nobot ) + db = 65536; + else + db = + mpeg2_fullsearch( + botorg, botref, mb, mpeg2_width << 1, i, j, sx, sy>>1, 8, mpeg2_width, + mpeg2_height >> 1, &iminb, &jminb ); + + /* select prediction for upper half field */ + if ( dt <= db ) { + *d8p = dt; + *imin8up = imint; + *jmin8up = jmint; + *sel8up = 0; + } else { + *d8p = db; + *imin8up = iminb; + *jmin8up = jminb; + *sel8up = 1; + } + + /* predict lower half field from top field */ + if ( notop ) + dt = 65536; + else + dt = + mpeg2_fullsearch( + toporg, topref, mb + ( mpeg2_width << 4 ), mpeg2_width << 1, i, j + 8, + sx, sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &imint, &jmint ); + + /* predict lower half field from bottom field */ + if ( nobot ) + db = 65536; + else + db = + mpeg2_fullsearch( + botorg, botref, mb + ( mpeg2_width << 4 ), mpeg2_width << 1, i, j + 8, + sx, sy >> 1, 8, mpeg2_width, mpeg2_height >> 1, &iminb, &jminb ); + + /* select prediction for lower half field */ + if ( dt <= db ) { + *d8p += dt; + *imin8lp = imint; + *jmin8lp = jmint; + *sel8lp = 0; + } else { + *d8p += db; + *imin8lp = iminb; + *jmin8lp = jminb; + *sel8lp = 1; + } +} + + +void mpeg2_dpframe_estimate( unsigned char *ref, unsigned char *mb, int i, + int j, int iminf[ 2 ][ 2 ], int jminf[ 2 ][ 2 ], + int *iminp, int *jminp, int *imindmvp, + int *jmindmvp, int *dmcp, int *vmcp ) +{ + int pref, ppred, delta_x, delta_y; + int is, js, it, jt, ib, jb, it0, jt0, ib0, jb0; + int imins, jmins, imint, jmint, iminb, jminb, imindmv, jmindmv; + int vmc, local_dist; + + + /* + Calculate Dual Prime distortions for 9 delta candidates + for each of the four minimum field vectors + Note: only for P pictures! + */ + + /* initialize minimum dual prime distortion to large value */ + vmc = 1 << 30; + + _Pragma( "loopbound min 2 max 2" ) + for ( pref = 0; pref < 2; pref++ ) { + ppred = 0; + _Pragma( "loopbound min 2 max 2" ) + for ( ; ppred < 2; ppred++ ) { + /* + convert Cartesian absolute to relative motion vector + values (wrt current macroblock address (i,j) + */ + is = iminf[ pref ][ ppred ] - ( i << 1 ); + js = jminf[ pref ][ ppred ] - ( j << 1 ); + + if ( pref != ppred ) { + /* vertical field shift adjustment */ + if ( ppred == 0 ) + js++; + else + js--; + + /* mvxs and mvys scaling*/ + is <<= 1; + js <<= 1; + if ( mpeg2_topfirst == ppred ) { + /* second field: scale by 1/3 */ + is = ( is >= 0 ) ? ( is + 1 ) / 3 : -( ( -is + 1 ) / 3 ); + js = ( js >= 0 ) ? ( js + 1 ) / 3 : -( ( -js + 1 ) / 3 ); + } else + continue; + } + + /* vector for prediction from field of opposite 'parity' */ + if ( mpeg2_topfirst ) { + /* vector for prediction of top field from bottom field */ + it0 = ( ( is + ( is > 0 ) ) >> 1 ); + jt0 = ( ( js + ( js > 0 ) ) >> 1 ) - 1; + + /* vector for prediction of bottom field from top field */ + ib0 = ( ( 3 * is + ( is > 0 ) ) >> 1 ); + jb0 = ( ( 3 * js + ( js > 0 ) ) >> 1 ) + 1; + } else { + /* vector for prediction of top field from bottom field */ + it0 = ( ( 3 * is + ( is > 0 ) ) >> 1 ); + jt0 = ( ( 3 * js + ( js > 0 ) ) >> 1 ) - 1; + + /* vector for prediction of bottom field from top field */ + ib0 = ( ( is + ( is > 0 ) ) >> 1 ); + jb0 = ( ( js + ( js > 0 ) ) >> 1 ) + 1; + } + + /* convert back to absolute half-pel field picture coordinates */ + is += i << 1; + js += j << 1; + it0 += i << 1; + jt0 += j << 1; + ib0 += i << 1; + jb0 += j << 1; + + if ( ( is >= 0 ) && ( is <= ( mpeg2_width - 16 ) << 1 ) && + ( js >= 0 ) && ( js <= ( mpeg2_height - 16 ) ) ) { + _Pragma( "loopbound min 3 max 3" ) + for ( delta_y = -1; delta_y <= 1; delta_y++ ) { + delta_x = -1; + _Pragma( "loopbound min 3 max 3" ) + for ( ; delta_x <= 1; delta_x++ ) { + /* opposite field coordinates */ + it = it0 + delta_x; + jt = jt0 + delta_y; + ib = ib0 + delta_x; + jb = jb0 + delta_y; + + if ( ( it >= 0 ) && ( it <= ( mpeg2_width - 16 ) << 1 ) && + ( jt >= 0 ) && ( jt <= ( mpeg2_height - 16 ) ) && + ( ib >= 0 ) && ( ib <= ( mpeg2_width - 16 ) << 1 ) && + ( jb >= 0 ) && ( jb <= ( mpeg2_height - 16 ) ) ) { + /* compute prediction error */ + local_dist = + mpeg2_bdist2( + ref + ( is >> 1 ) + ( mpeg2_width << 1 ) * ( js >> 1 ), + ref + mpeg2_width + ( it >> 1 ) + + ( mpeg2_width << 1 ) * ( jt >> 1 ), + mb, /* current mb location */ + mpeg2_width << 1, /* adjacent line distance */ + is & 1, js & 1, it & 1, jt & 1, /* half-pel flags */ + 8 ); /* block height */ + local_dist += + mpeg2_bdist2( + ref + mpeg2_width + ( is >> 1 ) + + ( mpeg2_width << 1 ) * ( js >> 1 ), + ref + ( ib >> 1 ) + ( mpeg2_width << 1 ) * ( jb >> 1 ), + mb + mpeg2_width, /* current mb location */ + mpeg2_width << 1, /* adjacent line distance */ + is & 1, js & 1, ib & 1, jb & 1, /* half-pel flags */ + 8 ); /* block height */ + + /* update delta with least distortion vector */ + if ( local_dist < vmc ) { + imins = is; + jmins = js; + imint = it; + jmint = jt; + iminb = ib; + jminb = jb; + imindmv = delta_x; + jmindmv = delta_y; + vmc = local_dist; + } + } + } /* end delta x loop */ + } /* end delta y loop */ + } + } + } + + /* Compute L1 error for decision purposes */ + local_dist = + mpeg2_bdist1( + ref + ( imins >> 1 ) + ( mpeg2_width << 1 ) * ( jmins >> 1 ), + ref + mpeg2_width + ( imint >> 1 ) + + ( mpeg2_width << 1 ) * ( jmint >> 1 ), + mb, mpeg2_width << 1, imins & 1, jmins & 1, imint & 1, jmint & 1, 8 ); + local_dist += + mpeg2_bdist1( + ref + mpeg2_width + ( imins >> 1 ) + + ( mpeg2_width << 1 ) * ( jmins >> 1 ), + ref + ( iminb >> 1 ) + ( mpeg2_width << 1 ) * ( jminb >> 1 ), + mb + mpeg2_width, mpeg2_width << 1, imins & 1, jmins & 1, iminb & 1, + jminb & 1, 8 ); + + *dmcp = local_dist; + *iminp = imins; + *jminp = jmins; + *imindmvp = imindmv; + *jmindmvp = jmindmv; + *vmcp = vmc; +} + + +void mpeg2_dpfield_estimate( unsigned char *topref, unsigned char *botref, + unsigned char *mb, int i, int j, int imins, + int jmins, int *imindmvp, int *jmindmvp, int *dmcp, + int *vmcp ) +{ + unsigned char *sameref, *oppref; + int io0, jo0, io, jo, delta_x, delta_y, mvxs, mvys, mvxo0, mvyo0; + int imino, jmino, imindmv, jmindmv, vmc_dp, local_dist; + + + /* Calculate Dual Prime distortions for 9 delta candidates */ + /* Note: only for P pictures! */ + + /* Assign opposite and same reference pointer */ + if ( mpeg2_pict_struct == 1 ) { + sameref = topref; + oppref = botref; + } else { + sameref = botref; + oppref = topref; + } + + /* + convert Cartesian absolute to relative motion vector + values (wrt current macroblock address (i,j) + */ + mvxs = imins - ( i << 1 ); + mvys = jmins - ( j << 1 ); + + /* vector for prediction from field of opposite 'parity' */ + mvxo0 = ( mvxs + ( mvxs > 0 ) ) >> 1; /* mvxs // 2 */ + mvyo0 = ( mvys + ( mvys > 0 ) ) >> 1; /* mvys // 2 */ + + /* vertical field shift correction */ + if ( mpeg2_pict_struct == 1 ) + mvyo0--; + else + mvyo0++; + + /* convert back to absolute coordinates */ + io0 = mvxo0 + ( i << 1 ); + jo0 = mvyo0 + ( j << 1 ); + + /* initialize minimum dual prime distortion to large value */ + vmc_dp = 1 << 30; + + _Pragma( "loopbound min 3 max 3" ) + for ( delta_y = -1; delta_y <= 1; delta_y++ ) { + delta_x = -1; + _Pragma( "loopbound min 3 max 3" ) + for ( ; delta_x <= 1; delta_x++ ) { + /* opposite field coordinates */ + io = io0 + delta_x; + jo = jo0 + delta_y; + + if ( ( io >= 0 ) && ( io <= ( mpeg2_width - 16 ) << 1 ) && + ( jo >= 0 ) && ( jo <= ( mpeg2_height2 - 16 ) << 1 ) ) { + /* compute prediction error */ + local_dist = + mpeg2_bdist2( + sameref + ( imins >> 1 ) + mpeg2_width2 * ( jmins >> 1 ), + oppref + ( io >> 1 ) + mpeg2_width2 * ( jo >> 1 ), + mb, /* current mb location */ + mpeg2_width2, /* adjacent line distance */ + imins & 1, jmins & 1, io & 1, jo & 1, /* half-pel flags */ + 16 ); /* block height */ + + /* update delta with least distortion vector */ + if ( local_dist < vmc_dp ) { + imino = io; + jmino = jo; + imindmv = delta_x; + jmindmv = delta_y; + vmc_dp = local_dist; + } + } + } /* end delta x loop */ + } /* end delta y loop */ + + /* Compute L1 error for decision purposes */ + *dmcp = + mpeg2_bdist1( + sameref + ( imins >> 1 ) + mpeg2_width2 * ( jmins >> 1 ), + oppref + ( imino >> 1 ) + mpeg2_width2 * ( jmino >> 1 ), + mb, /* current mb location */ + mpeg2_width2, /* adjacent line distance */ + imins & 1, jmins & 1, imino & 1, jmino & 1, /* half-pel flags */ + 16 ); /* block height */ + + *imindmvp = imindmv; + *jmindmvp = jmindmv; + *vmcp = vmc_dp; +} + + +/* + full search block matching + + blk: top left pel of (16*h) block + h: height of block + lx: distance (in bytes) of vertically adjacent pels in ref,blk + org: top left pel of source reference picture + ref: top left pel of reconstructed reference picture + i0,j0: center of search window + sx,sy: half widths of search window + xmax,ymax: right/bottom limits of search area + iminp,jminp: pointers to where the result is stored + result is given as half pel offset from ref(0,0) + i.e. NOT relative to (i0,j0) +*/ +int mpeg2_fullsearch( unsigned char *org, unsigned char *ref, + unsigned char *blk, int lx, int i0, int j0, int sx, + int sy, int h, int xmax, int ymax, int *iminp, + int *jminp ) +{ + int i, j, imin, jmin, ilow, ihigh, jlow, jhigh; + int d, dmin; + int k, l, sxy; + + + ilow = i0 - sx; + ihigh = i0 + sx; + + if ( ilow < 0 ) + ilow = 0; + + if ( ihigh > xmax - 16 ) + ihigh = xmax - 16; + + jlow = j0 - sy; + jhigh = j0 + sy; + + if ( jlow < 0 ) + jlow = 0; + + if ( jhigh > ymax - h ) + jhigh = ymax - h; + + /* full pel search, spiraling outwards */ + + imin = i0; + jmin = j0; + dmin = mpeg2_dist1( org + imin + lx * jmin, blk, lx, 0, 0, h, 65536 ); + + sxy = ( sx > sy ) ? sx : sy; + + _Pragma( "loopbound min 3 max 7" ) + for ( l = 1; l <= sxy; l++ ) { + i = i0 - l; + j = j0 - l; + _Pragma( "loopbound min 8 max 56" ) + for ( k = 0; k < 8 * l; k++ ) { + if ( ( i >= ilow ) && ( i <= ihigh ) && ( j >= jlow ) && + ( j <= jhigh ) ) { + d = mpeg2_dist1( org + i + lx * j, blk, lx, 0, 0, h, dmin ); + + if ( d < dmin ) { + dmin = d; + imin = i; + jmin = j; + } + } + + if ( k < 2 * l ) + i++; + else + + if ( k < 4 * l ) + j++; + else + + if ( k < 6 * l ) + i--; + else + j--; + } + } + + /* half pel */ + dmin = 65536; + imin <<= 1; + jmin <<= 1; + ilow = imin - ( imin > 0 ); + ihigh = imin + ( imin < ( ( xmax - 16 ) << 1 ) ); + jlow = jmin - ( jmin > 0 ); + jhigh = jmin + ( jmin < ( ( ymax - h ) << 1 ) ); + + _Pragma( "loopbound min 2 max 3" ) + for ( j = jlow; j <= jhigh; j++ ) { + i = ilow; + _Pragma( "loopbound min 2 max 3" ) + for ( ; i <= ihigh; i++ ) { + d = + mpeg2_dist1( + ref + ( i >> 1 ) + lx * ( j >> 1 ), blk, lx, i & 1, j & 1, h, dmin ); + + if ( d < dmin ) { + dmin = d; + imin = i; + jmin = j; + } + } + } + + *iminp = imin; + *jminp = jmin; + + return( dmin ); +} + + +/* + total absolute difference between two (16*h) blocks + including optional half pel interpolation of blk1 (hx,hy) + blk1,blk2: addresses of top left pels of both blocks + lx: distance (in bytes) of vertically adjacent pels + hx,hy: flags for horizontal and/or vertical interpolation + h: height of block (usually 8 or 16) + distlim: bail out if sum exceeds this value +*/ +int mpeg2_dist1( unsigned char *blk1, unsigned char *blk2, int lx, int hx, + int hy, int h, int distlim ) +{ + unsigned char *p1, *p1a, *p2; + int i, j; + int s, v; + + + s = 0; + p1 = blk1; + p2 = blk2; + + if ( !hx && !hy ) { + _Pragma( "loopbound min 1 max 16" ) + for ( j = 0; j < h; j++ ) { + if ( ( v = p1[ 0 ] - p2[ 0 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 1 ] - p2[ 1 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 2 ] - p2[ 2 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 3 ] - p2[ 3 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 4 ] - p2[ 4 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 5 ] - p2[ 5 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 6 ] - p2[ 6 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 7 ] - p2[ 7 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 8 ] - p2[ 8 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 9 ] - p2[ 9 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 10 ] - p2[ 10 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 11 ] - p2[ 11 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 12 ] - p2[ 12 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 13 ] - p2[ 13 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 14 ] - p2[ 14 ] ) < 0 ) + v = -v; + s += v; + + if ( ( v = p1[ 15 ] - p2[ 15 ] ) < 0 ) + v = -v; + s += v; + + if ( s >= distlim ) + break; + + p1 += lx; + p2 += lx; + } + } else + + if ( hx && !hy ) { + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1[ i + 1 ] + 1 ) >> 1 ) - p2[ i ]; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p1 += lx; + p2 += lx; + } + } else + + if ( !hx && hy ) { + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1a[ i ] + 1 ) >> 1 ) - p2[ i ]; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } else { /* if (hx && hy) */ + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( unsigned int ) + ( p1[ i ] + p1[ i + 1 ] + p1a[ i ] + p1a[ i + 1 ] + 2 ) >> 2 ) - + p2[ i ]; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } + + return( s ); +} + + +/* + total squared difference between two (16*h) blocks + including optional half pel interpolation of blk1 (hx,hy) + blk1,blk2: addresses of top left pels of both blocks + lx: distance (in bytes) of vertically adjacent pels + hx,hy: flags for horizontal and/or vertical interpolation + h: height of block (usually 8 or 16) +*/ +int mpeg2_dist2( unsigned char *blk1, unsigned char *blk2, int lx, int hx, + int hy, int h ) +{ + unsigned char *p1, *p1a, *p2; + int i, j; + int s, v; + + + s = 0; + p1 = blk1; + p2 = blk2; + + if ( !hx && !hy ) { + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = p1[ i ] - p2[ i ]; + s += v * v; + } + p1 += lx; + p2 += lx; + } + } else + + if ( hx && !hy ) { + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1[ i + 1 ] + 1 ) >> 1 ) - p2[ i ]; + s += v * v; + } + p1 += lx; + p2 += lx; + } + } else + + if ( !hx && hy ) { + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = ( ( unsigned int )( p1[ i ] + p1a[ i ] + 1 ) >> 1 ) - p2[ i ]; + s += v * v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } else { /* if (hx && hy) */ + p1a = p1 + lx; + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( unsigned int ) + ( p1[ i ] + p1[ i + 1 ] + p1a[ i ] + p1a[ i + 1 ] + 2 ) >> 2 ) - + p2[ i ]; + s += v * v; + } + p1 = p1a; + p1a += lx; + p2 += lx; + } + } + + return( s ); +} + + +/* + absolute difference error between a (16*h) block and a bidirectional + prediction + + p2: address of top left pel of block + pf,hxf,hyf: address and half pel flags of forward ref. block + pb,hxb,hyb: address and half pel flags of backward ref. block + h: height of block + lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb +*/ +int mpeg2_bdist1( unsigned char *pf, unsigned char *pb, unsigned char *p2, + int lx, int hxf, int hyf, int hxb, int hyb, int h ) +{ + unsigned char *pfa, *pfb, *pfc, *pba, *pbb, *pbc; + int i, j; + int s, v; + + + pfa = pf + hxf; + pfb = pf + lx * hyf; + pfc = pfb + hxf; + + pba = pb + hxb; + pbb = pb + lx * hyb; + pbc = pbb + hxb; + + s = 0; + + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( ( ( unsigned int )( *pf++ + *pfa++ + *pfb++ + *pfc++ + 2 ) >> 2 ) + + ( ( unsigned int )( *pb++ + *pba++ + *pbb++ + *pbc++ + 2 ) >> 2 ) + + 1 ) >> 1 ) - + *p2++; + if ( v >= 0 ) + s += v; + else + s -= v; + } + p2 += lx - 16; + pf += lx - 16; + pfa += lx - 16; + pfb += lx - 16; + pfc += lx - 16; + pb += lx - 16; + pba += lx - 16; + pbb += lx - 16; + pbc += lx - 16; + } + + return( s ); +} + + +/* + squared error between a (16*h) block and a bidirectional + prediction + + p2: address of top left pel of block + pf,hxf,hyf: address and half pel flags of forward ref. block + pb,hxb,hyb: address and half pel flags of backward ref. block + h: height of block + lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb +*/ +int mpeg2_bdist2( unsigned char *pf, unsigned char *pb, unsigned char *p2, + int lx, int hxf, int hyf, int hxb, int hyb, int h ) +{ + unsigned char *pfa, *pfb, *pfc, *pba, *pbb, *pbc; + int i, j; + int s, v; + + + pfa = pf + hxf; + pfb = pf + lx * hyf; + pfc = pfb + hxf; + + pba = pb + hxb; + pbb = pb + lx * hyb; + pbc = pbb + hxb; + + s = 0; + + _Pragma( "loopbound min 8 max 16" ) + for ( j = 0; j < h; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = + ( ( ( ( unsigned int )( *pf++ + *pfa++ + *pfb++ + *pfc++ + 2 ) >> 2 ) + + ( ( unsigned int )( *pb++ + *pba++ + *pbb++ + *pbc++ + 2 ) >> 2 ) + + 1 ) >> 1 ) - + *p2++; + s += v * v; + } + p2 += lx - 16; + pf += lx - 16; + pfa += lx - 16; + pfb += lx - 16; + pfc += lx - 16; + pb += lx - 16; + pba += lx - 16; + pbb += lx - 16; + pbc += lx - 16; + } + + return( s ); +} + + +/* + variance of a (16*16) block, multiplied by 256 + p: address of top left pel of block + lx: distance (in bytes) of vertically adjacent pels +*/ +int mpeg2_variance( unsigned char *p, int lx ) +{ + int i, j; + unsigned int v, s, s2; + + + s = s2 = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( j = 0; j < 16; j++ ) { + i = 0; + _Pragma( "loopbound min 16 max 16" ) + for ( ; i < 16; i++ ) { + v = *p++; + s += v; + s2 += v * v; + } + p += lx - 16; + } + + return( s2 - ( s * s ) / 256 ); +} + + +/* + Main functions +*/ + +void _Pragma ( "entrypoint" ) mpeg2_main( void ) +{ + mpeg2_motion_estimation( + mpeg2_oldorgframe, mpeg2_oldorgframe, mpeg2_oldorgframe, mpeg2_oldorgframe, + mpeg2_oldorgframe, mpeg2_oldorgframe, 7, 7, 3, 3, mpeg2_mbinfo, 0, 0 ); +} + + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= 1; j--, k-- ) { + ndes_icd.r = ( ndes_icd.r << 1 ) | ndes_getbit( key, ndes_ipc1[j], 32 ); + ndes_icd.l = ndes_icd.l << 1; + ndes_icd.l = ( ndes_icd.l ) | ndes_getbit( key, ndes_ipc1[k], 32 ); + } + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 1; i <= 16; i++ ) { + pg = kns[i]; + ndes_ks( /* key,*/ i, &pg ); + kns[i] = pg; + } + } + + itmp.r = itmp.l = 0L; + + _Pragma( "loopbound min 32 max 32" ) + for ( j = 32, k = 64; j >= 1; j--, k-- ) { + itmp.r = itmp.r << 1; + itmp.r = ( itmp.r ) | ndes_getbit( inp, ip[j], 32 ); + itmp.l = itmp.l << 1; + itmp.l = ( itmp.l ) | ndes_getbit( inp, ip[k], 32 ); + } + _Pragma( "loopbound min 16 max 16" ) + for ( i = 1; i <= 16; i++ ) { + ii = ( isw == 1 ? 17 - i : i ); + ndes_cyfun( itmp.l, kns[ii], &ic ); + ic ^= itmp.r; + itmp.r = itmp.l; + itmp.l = ic; + } + + ic = itmp.r; + itmp.r = itmp.l; + itmp.l = ic; + ( *out ).r = ( *out ).l = 0L; + + _Pragma( "loopbound min 32 max 32" ) + for ( j = 32, k = 64; j >= 1; j--, k-- ) { + ( *out ).r = ( *out ).r << 1; + ( *out ).r = ( ( *out ).r ) | ndes_getbit( itmp, ipm[j], 32 ); + ( *out ).l = ( *out ).l << 1; + ( *out ).l = ( ( *out ).l ) | ndes_getbit( itmp, ipm[k], 32 ); + } +} + + +void ndes_cyfun( unsigned long ir, ndes_great k, unsigned long *iout ) +{ + volatile long iet[49] = {0, 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, + 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, + 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 + }; + volatile long ipp[33] = {0, 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, + 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, + 30, 6, 22, 11, 4, 25 + }; + volatile long is[16][4][9] = {{{ 0 , 14 , 15 , 10 , 7 , 2 , 12 , 4 , 13 }, + { 0 , 0 , 3 , 13 , 13 , 14 , 10 , 13 , 1 }, + { 0 , 4 , 0 , 13 , 10 , 4 , 9 , 1 , 7 }, + { 0 , 15 , 13 , 1 , 3 , 11 , 4 , 6 , 2 }}, + {{ 0 , 4 , 1 , 0 , 13 , 12 , 1 , 11 , 2 }, + { 0 , 15 , 13 , 7 , 8 , 11 , 15 , 0 , 15 }, + { 0 , 1 , 14 , 6 , 6 , 2 , 14 , 4 , 11 }, + { 0 , 12 , 8 , 10 , 15 , 8 , 3 , 11 , 1 }}, + {{ 0 , 13 , 8 , 9 , 14 , 4 , 10 , 2 , 8 }, + { 0 , 7 , 4 , 0 , 11 , 2 , 4 , 11 , 13 }, + { 0 , 14 , 7 , 4 , 9 , 1 , 15 , 11 , 4 }, + { 0 , 8 , 10 , 13 , 0 , 12 , 2 , 13 , 14 }}, + {{ 0 , 1 , 14 , 14 , 3 , 1 , 15 , 14 , 4 }, + { 0 , 4 , 7 , 9 , 5 , 12 , 2 , 7 , 8 }, + { 0 , 8 , 11 , 9 , 0 , 11 , 5 , 13 , 1 }, + { 0 , 2 , 1 , 0 , 6 , 7 , 12 , 8 , 7 }}, + {{ 0 , 2 , 6 , 6 , 0 , 7 , 9 , 15 , 6 }, + { 0 , 14 , 15 , 3 , 6 , 4 , 7 , 4 , 10 }, + { 0 , 13 , 10 , 8 , 12 , 10 , 2 , 12 , 9 }, + { 0 , 4 , 3 , 6 , 10 , 1 , 9 , 1 , 4 }}, + {{ 0 , 15 , 11 , 3 , 6 , 10 , 2 , 0 , 15 }, + { 0 , 2 , 2 , 4 , 15 , 7 , 12 , 9 , 3 }, + { 0 , 6 , 4 , 15 , 11 , 13 , 8 , 3 , 12 }, + { 0 , 9 , 15 , 9 , 1 , 14 , 5 , 4 , 10 }}, + {{ 0 , 11 , 3 , 15 , 9 , 11 , 6 , 8 , 11 }, + { 0 , 13 , 8 , 6 , 0 , 13 , 9 , 1 , 7 }, + { 0 , 2 , 13 , 3 , 7 , 7 , 12 , 7 , 14 }, + { 0 , 1 , 4 , 8 , 13 , 2 , 15 , 10 , 8 }}, + {{ 0 , 8 , 4 , 5 , 10 , 6 , 8 , 13 , 1 }, + { 0 , 1 , 14 , 10 , 3 , 1 , 5 , 10 , 4 }, + { 0 , 11 , 1 , 0 , 13 , 8 , 3 , 14 , 2 }, + { 0 , 7 , 2 , 7 , 8 , 13 , 10 , 7 , 13 }}, + {{ 0 , 3 , 9 , 1 , 1 , 8 , 0 , 3 , 10 }, + { 0 , 10 , 12 , 2 , 4 , 5 , 6 , 14 , 12 }, + { 0 , 15 , 5 , 11 , 15 , 15 , 7 , 10 , 0 }, + { 0 , 5 , 11 , 4 , 9 , 6 , 11 , 9 , 15 }}, + {{ 0 , 10 , 7 , 13 , 2 , 5 , 13 , 12 , 9 }, + { 0 , 6 , 0 , 8 , 7 , 0 , 1 , 3 , 5 }, + { 0 , 12 , 8 , 1 , 1 , 9 , 0 , 15 , 6 }, + { 0 , 11 , 6 , 15 , 4 , 15 , 14 , 5 , 12 }}, + {{ 0 , 6 , 2 , 12 , 8 , 3 , 3 , 9 , 3 }, + { 0 , 12 , 1 , 5 , 2 , 15 , 13 , 5 , 6 }, + { 0 , 9 , 12 , 2 , 3 , 12 , 4 , 6 , 10 }, + { 0 , 3 , 7 , 14 , 5 , 0 , 1 , 0 , 9 }}, + {{ 0 , 12 , 13 , 7 , 5 , 15 , 4 , 7 , 14 }, + { 0 , 11 , 10 , 14 , 12 , 10 , 14 , 12 , 11 }, + { 0 , 7 , 6 , 12 , 14 , 5 , 10 , 8 , 13 }, + { 0 , 14 , 12 , 3 , 11 , 9 , 7 , 15 , 0 }}, + {{ 0 , 5 , 12 , 11 , 11 , 13 , 14 , 5 , 5 }, + { 0 , 9 , 6 , 12 , 1 , 3 , 0 , 2 , 0 }, + { 0 , 3 , 9 , 5 , 5 , 6 , 1 , 0 , 15 }, + { 0 , 10 , 0 , 11 , 12 , 10 , 6 , 14 , 3 }}, + {{ 0 , 9 , 0 , 4 , 12 , 0 , 7 , 10 , 0 }, + { 0 , 5 , 9 , 11 , 10 , 9 , 11 , 15 , 14 }, + { 0 , 10 , 3 , 10 , 2 , 3 , 13 , 5 , 3 }, + { 0 , 0 , 5 , 5 , 7 , 4 , 0 , 2 , 5 }}, + {{ 0 , 0 , 5 , 2 , 4 , 14 , 5 , 6 , 12 }, + { 0 , 3 , 11 , 15 , 14 , 8 , 3 , 8 , 9 }, + { 0 , 5 , 2 , 14 , 8 , 0 , 11 , 9 , 5 }, + { 0 , 6 , 14 , 2 , 2 , 5 , 8 , 3 , 6 }}, + {{ 0 , 7 , 10 , 8 , 15 , 9 , 11 , 1 , 7 }, + { 0 , 8 , 5 , 1 , 9 , 6 , 8 , 6 , 2 }, + { 0 , 0 , 15 , 7 , 4 , 14 , 6 , 2 , 8 }, + { 0 , 13 , 9 , 12 , 14 , 3 , 13 , 12 , 11 }}}; + + volatile char ibin[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; + ndes_great ie; + unsigned long itmp, ietmp1, ietmp2; + char iec[9]; + int irow, icol, iss, l, m; + int volatile j, jj; + unsigned long *p; + + p = ndes_bit; + ie.r = ie.c = ie.l = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( j = 16, l = 32, m = 48; j >= 1; j--, l--, m-- ) { + ie.r = ( ie.r << 1 ) | ( p[iet[j]] & ir ? 1 : 0 ); + ie.c = ( ie.c << 1 ) | ( p[iet[l]] & ir ? 1 : 0 ); + ie.l = ( ie.l << 1 ) | ( p[iet[m]] & ir ? 1 : 0 ); + } + ie.r ^= k.r; + ie.c ^= k.c; + ie.l ^= k.l; + ietmp1 = ( ( unsigned long ) ie.c << 16 ) + ( unsigned long ) ie.r; + ietmp2 = ( ( unsigned long ) ie.l << 8 ) + ( ( unsigned long ) ie.c >> 8 ); + + _Pragma( "loopbound min 4 max 4" ) + for ( j = 1, m = 5; j <= 4; j++, m++ ) { + iec[j] = ietmp1 & 0x3fL; + iec[m] = ietmp2 & 0x3fL; + ietmp1 >>= 6; + ietmp2 >>= 6; + } + + itmp = 0L; + + _Pragma( "loopbound min 8 max 8" ) + for ( jj = 8; jj >= 1; jj-- ) { + j = iec[jj]; + irow = ( ( j & 0x1 ) << 1 ) + ( ( j & 0x20 ) >> 5 ); + icol = ( ( j & 0x2 ) << 2 ) + ( j & 0x4 ) + + ( ( j & 0x8 ) >> 2 ) + ( ( j & 0x10 ) >> 4 ); + iss = is[icol][irow][jj]; + itmp = ( itmp << 4 ) | ibin[iss]; + } + + *iout = 0L; + p = ndes_bit; + + _Pragma( "loopbound min 32 max 32" ) + for ( j = 32; j >= 1; j-- ) + *iout = ( *iout << 1 ); + *iout |= ( p[ipp[j]] & itmp ? 1 : 0 ); +} + +unsigned long ndes_getbit( ndes_immense source, int bitno, int nbits ) +{ + if ( bitno <= nbits ) + return ndes_bit[bitno] & source.r ? 1L : 0L; + else + return ndes_bit[bitno - nbits] & source.l ? 1L : 0L; +} + +void ndes_ks( /*ndes_immense key, */int n, ndes_great *kn ) +{ + int i, j, k, l; + + if ( n == 1 || n == 2 || n == 9 || n == 16 ) { + ndes_icd.r = ( ndes_icd.r | ( ( ndes_icd.r & 1L ) << 28 ) ) >> 1; + ndes_icd.l = ( ndes_icd.l | ( ( ndes_icd.l & 1L ) << 28 ) ) >> 1; + } else { + _Pragma( "loopbound min 2 max 2" ) + for ( i = 1; i <= 2; i++ ) { + ndes_icd.r = ( ndes_icd.r | ( ( ndes_icd.r & 1L ) << 28 ) ) >> 1; + ndes_icd.l = ( ndes_icd.l | ( ( ndes_icd.l & 1L ) << 28 ) ) >> 1; + } + } + + ( *kn ).r = ( *kn ).c = ( *kn ).l = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( j = 16, k = 32, l = 48; j >= 1; j--, k--, l-- ) { + ( *kn ).r = ( *kn ).r << 1; + ( *kn ).r = ( ( *kn ).r ) | ( unsigned short ) + ndes_getbit( ndes_icd, ndes_ipc2[j], 28 ); + ( *kn ).c = ( *kn ).c << 1; + ( *kn ).c = ( ( *kn ).c ) | ( unsigned short ) + ndes_getbit( ndes_icd, ndes_ipc2[k], 28 ); + ( *kn ).l = ( *kn ).l << 1; + ( *kn ).l = ( ( *kn ).l ) | ( unsigned short ) + ndes_getbit( ndes_icd, ndes_ipc2[l], 28 ); + } +} + +int ndes_return() +{ + return (ndes_icd.r+ndes_icd.l + (-8390656) ) != 0 ; +} + +void _Pragma( "entrypoint" ) ndes_main() +{ + ndes_des( ndes_inp, ndes_key, &ndes_newkey, ndes_isw, &ndes_out ); +} + +/* main function */ + +int main( int argc, char **argv ) +{ + SET_UP + for(jobsComplete=-1; jobsComplete petrinet_main_iters_dummy_i + - main_min_dummy_i -> petrinet_main_min_dummy_i + - main_max_dummy_i -> petrinet_main_max_dummy_i + - P1_is_marked -> petrinet_P1_is_marked + - P1_marking_member_0 -> petrinet_P1_marking_member_0 + - P2_is_marked -> petrinet_P2_is_marked + - P2_marking_member_0 -> petrinet_P2_marking_member_0 + - P3_is_marked -> petrinet_P3_is_marked + - P3_marking_member_0 -> petrinet_P3_marking_member_0 +- Renamed main function to petrinet_main, set as entrypoint. +- Implemented new function main according to TACLeBench guidelines. +- Implemented function petrinet_return, calculates checksum over + petrinet_P3_marking_member_0. +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: bs_) followed by lowercase letter (e.g., bs_square) + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - Operators within expressions shall be preceded and followed by one + whitespace + +2016-04-05: +- Return '0' on success + +2016-04-06: +- Fixed generation of return value + +2016-06-01: +- Changed all prefixes to lower-case + +2016-06-08: +- Prefix +- removed return from petrinet_main + +2016-06-13: +- introduced function petrinet_init diff --git a/baseline/source/petrinet/petrinet.c b/baseline/source/petrinet/petrinet.c new file mode 100644 index 0000000..7c9e1a0 --- /dev/null +++ b/baseline/source/petrinet/petrinet.c @@ -0,0 +1,990 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: Petrinet + + Author: Friedhelm Stappert, C-LAB, Paderborn, Germany + + Function: Simulate an extended Petri Net + Automatically generated code containing large amounts of + if-statements (more than 250) + + Source: Mälardalen benchmark suite + + Changes: no major functional changes + + License: may be used, modified, and re-distributed freely + +*/ + +/* Remove the following #define for actual WCET analyses! */ +/* + #define PROFILING +*/ + + +#include "../extra.h" + +#ifdef PROFILING +#include +#endif + +#ifdef PROFILING +/* Profiling variables. Remove for actual WCET analyses. */ +int petrinet_main_iters_dummy_i = 0, + petrinet_main_min_dummy_i = 100000, + petrinet_main_max_dummy_i = 0; +#endif + +/* + Forward declaration of functions +*/ +void petrinet_init( void ); +int petrinet_return( void ); +void petrinet_main( void ); +//int main( void ); + + +volatile int petrinet_P1_is_marked; +volatile long petrinet_P1_marking_member_0[ 3 ]; +volatile int petrinet_P2_is_marked; +volatile long petrinet_P2_marking_member_0[ 5 ]; +volatile int petrinet_P3_is_marked; +volatile long petrinet_P3_marking_member_0[ 6 ]; + +const long petrinet_CHECKSUM = 0; + +void _Pragma ( "entrypoint" ) petrinet_main( void ) +{ + int dummy_i; + /* dummy_i = 17; Takes too much time */ + dummy_i = 2; + + #ifdef PROFILING + main_iters_dummy_i = 0; + #endif + _Pragma( "loopbound min 2 max 2" ) + while ( dummy_i > 0 ) { + #ifdef PROFILING + main_iters_dummy_i++; + #endif + + dummy_i--; + /* Permutation for Place P1 : 0, 1, 2 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 1 ] + == petrinet_P1_marking_member_0[ 2 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 0 ]; + y = petrinet_P1_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( x < y ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 0, 2, 1 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 2 ] + == petrinet_P1_marking_member_0[ 1 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 0 ]; + y = petrinet_P1_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 1, 0, 2 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 0 ] + == petrinet_P1_marking_member_0[ 2 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 1 ]; + y = petrinet_P1_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( x < y ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 1, 2, 0 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 2 ] + == petrinet_P1_marking_member_0[ 0 ] ) ) { + + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 1 ]; + y = petrinet_P1_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 2, 0, 1 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 0 ] + == petrinet_P1_marking_member_0[ 1 ] ) ) { + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 2 ]; + y = petrinet_P1_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P1 : 2, 1, 0 */ + /* Transition T1 */ + if ( ( petrinet_P1_is_marked >= 3 ) && + ( petrinet_P3_is_marked + 3 <= 6 ) && + ( petrinet_P1_marking_member_0[ 1 ] + == petrinet_P1_marking_member_0[ 0 ] ) ) { + long x; + long y; + long z; + + x = petrinet_P1_marking_member_0[ 2 ]; + y = petrinet_P1_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( x < y ) ) { + + /* demarking of input places */ + petrinet_P1_is_marked -= 3; + + /* preaction */ + z = x - y; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = x; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = y; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = z; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place P2 : 0, 1, 2, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( ( petrinet_P3_is_marked + 3 ) <= 6 ) ) && + ( ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 1, 3, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( ( petrinet_P3_is_marked + 3 ) <= 6 ) ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 2, 1, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 2, 3, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 3, 1, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 0, 3, 2, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 0 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 0, 2, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 0, 3, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 2, 0, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 2, 3, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 2 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 2 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 1, 3, 0, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + + /* Permutation for Place petrinet_P2 : 1, 3, 2, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 1 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + + /* Permutation for Place petrinet_P2 : 2, 0, 1, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 0, 3, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 1, 0, 3 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 1, 3, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 3 ] ) && + ( petrinet_P2_marking_member_0[ 1 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 1 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 3, 0, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 2, 3, 1, 0 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 3 ] + == petrinet_P2_marking_member_0[ 0 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 2 ]; + b = petrinet_P2_marking_member_0[ 3 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + /* Permutation for Place petrinet_P2 : 3, 0, 1, 2 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) ) ) { + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 3 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + + + /* Permutation for Place petrinet_P2 : 3, 0, 2, 1 */ + /* Transition T2 */ + if ( ( petrinet_P2_is_marked >= 4 ) && + ( ( petrinet_P3_is_marked + 3 ) <= 6 ) && + ( ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 2 ] ) && + ( petrinet_P2_marking_member_0[ 0 ] + == petrinet_P2_marking_member_0[ 1 ] ) ) ) { + + long a; + long b; + long c; + + a = petrinet_P2_marking_member_0[ 3 ]; + b = petrinet_P2_marking_member_0[ 0 ]; + + /* Transition condition */ + if ( ( b > a ) ) { + + /* demarking of input places */ + petrinet_P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 0 ] = a; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 1 ] = b; + petrinet_P3_marking_member_0[ petrinet_P3_is_marked + 2 ] = c; + petrinet_P3_is_marked += 3; + + } /* end of if (Transition condition) */ + } + } + #ifdef PROFILING + if ( main_iters_dummy_i < main_min_dummy_i ) + main_min_dummy_i = main_iters_dummy_i; + if ( main_iters_dummy_i > main_max_dummy_i ) + main_max_dummy_i = main_iters_dummy_i; + #endif + + #ifdef PROFILING + printf( "main::dummy_i-loop: [%d, %d]\n", + main_min_dummy_i, main_max_dummy_i ); + #endif + + //dummy_i = 77; + // TODO: not a good return value + //return dummy_i; +} + + +void petrinet_init( void ) +{ + petrinet_P1_is_marked = 3; + petrinet_P2_is_marked = 5; + petrinet_P3_is_marked = 0; + + /* + Maybe we should also initialise these arrays, as they may be read + in the petrinet_main() function before being written. + */ + /* + volatile long petrinet_P1_marking_member_0[ 3 ]; + volatile long petrinet_P2_marking_member_0[ 5 ]; + volatile long petrinet_P3_marking_member_0[ 6 ]; + */ +} + + +int petrinet_return( void ) +{ + // TODO: use something from the Px_... arrays + int checksum = 0; + int i; + + for ( i = 0; i < 3; ++i ) + checksum += petrinet_P1_marking_member_0[i]; + + for ( i = 0; i < 5; ++i ) + checksum += petrinet_P2_marking_member_0[i]; + + for ( i = 0; i < 6; ++i ) + checksum += petrinet_P3_marking_member_0[i]; + + return ( ( checksum == petrinet_CHECKSUM ) ? 0 : -1 ); +} + + +int main( int argc, char **argv ) +{ + SET_UP + + for (jobsComplete=-1; jobsComplete, Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of 128, + bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. +*/ + +#include "aes.h" + +#include "aestab.h" + +#define four_tables(x,tab,vf,rf,c) ( tab[0][bval(vf(x,0,c),rf(0,c))] ^ \ + tab[1][bval(vf(x,1,c),rf(1,c))] ^ \ + tab[2][bval(vf(x,2,c),rf(2,c))] ^ \ + tab[3][bval(vf(x,3,c),rf(3,c))] ) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((r-c)&3) + +#define ls_box(x,c) four_tables(x,rijndael_dec_fl_tab,vf1,rf2,c) + +#define inv_mcol(x) four_tables(x,rijndael_dec_im_tab,vf1,rf1,0) + +/* + Subroutine to set the block size (if variable) in bytes, legal + values being 16, 24 and 32. +*/ + +#define nc (Ncol) + +/* + Initialise the key schedule from the user supplied key. The key + length is now specified in bytes - 16, 24 or 32 as appropriate. + This corresponds to bit lengths of 128, 192 and 256 bits, and + to Nk values of 4, 6 and 8 respectively. +*/ + +#define mx(t,f) (*t++ = inv_mcol(*f),f++) +#define cp(t,f) *t++ = *f++ + +#define cpy(d,s) do { cp(d,s); cp(d,s); cp(d,s); cp(d,s); } while (0) +#define mix(d,s) do { mx(d,s); mx(d,s); mx(d,s); mx(d,s); } while (0) + +aes_ret rijndael_dec_set_key( byte in_key[], const word n_bytes, + const enum aes_key f, struct aes *cx ) +{ + word *kf, *kt, rci; + + if ( ( n_bytes & 7 ) || n_bytes < 16 || n_bytes > 32 || ( !( f & 1 ) && + !( f & 2 ) ) ) + return ( n_bytes ? cx->mode &= ~0x03, aes_bad : ( aes_ret )( cx->Nkey << 2 ) ); + + cx->mode = ( cx->mode & ~0x03 ) | ( ( byte )f & 0x03 ); + cx->Nkey = n_bytes >> 2; + cx->Nrnd = Nr( cx->Nkey, ( word )nc ); + + cx->e_key[0] = word_in( in_key ); + cx->e_key[1] = word_in( in_key + 4 ); + cx->e_key[2] = word_in( in_key + 8 ); + cx->e_key[3] = word_in( in_key + 12 ); + + kf = cx->e_key; + kt = kf + nc * ( cx->Nrnd + 1 ) - cx->Nkey; + rci = 0; + + switch ( cx->Nkey ) { + case 4: + _Pragma( "loopbound min 0 max 0" ) + do { + kf[4] = kf[0] ^ ls_box( kf[3], 3 ) ^ rijndael_dec_rcon_tab[rci++]; + kf[5] = kf[1] ^ kf[4]; + kf[6] = kf[2] ^ kf[5]; + kf[7] = kf[3] ^ kf[6]; + kf += 4; + } while ( kf < kt ); + break; + + case 6: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + _Pragma( "loopbound min 0 max 0" ) + do { + kf[ 6] = kf[0] ^ ls_box( kf[5], 3 ) ^ rijndael_dec_rcon_tab[rci++]; + kf[ 7] = kf[1] ^ kf[ 6]; + kf[ 8] = kf[2] ^ kf[ 7]; + kf[ 9] = kf[3] ^ kf[ 8]; + kf[10] = kf[4] ^ kf[ 9]; + kf[11] = kf[5] ^ kf[10]; + kf += 6; + } while ( kf < kt ); + break; + + case 8: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + cx->e_key[6] = word_in( in_key + 24 ); + cx->e_key[7] = word_in( in_key + 28 ); + _Pragma( "loopbound min 7 max 7" ) + do { + kf[ 8] = kf[0] ^ ls_box( kf[7], 3 ) ^ rijndael_dec_rcon_tab[rci++]; + kf[ 9] = kf[1] ^ kf[ 8]; + kf[10] = kf[2] ^ kf[ 9]; + kf[11] = kf[3] ^ kf[10]; + kf[12] = kf[4] ^ ls_box( kf[11], 0 ); + kf[13] = kf[5] ^ kf[12]; + kf[14] = kf[6] ^ kf[13]; + kf[15] = kf[7] ^ kf[14]; + kf += 8; + } while ( kf < kt ); + break; + } + + if ( ( cx->mode & 3 ) != enc ) { + word i; + + kt = cx->d_key + nc * cx->Nrnd; + kf = cx->e_key; + + cpy( kt, kf ); + kt -= 2 * nc; + + _Pragma( "loopbound min 0 max 0" ) + for ( i = 1; i < cx->Nrnd; ++i ) { + mix( kt, kf ); + kt -= 2 * nc; + } + + cpy( kt, kf ); + } + + return aes_good; +} + +short rijndael_dec_decrypt( const unsigned char in_blk[], + unsigned char out_blk[], const struct aes *cx ) +{ + const unsigned long *kp = cx->d_key; + if ( !( cx->mode & 2 ) ) + return 0; + unsigned long b0[4]; + b0[0] = *( unsigned long * )in_blk ^ kp[0]; + b0[1] = *( unsigned long * )( in_blk + 4 )^kp[1]; + b0[2] = *( unsigned long * )( in_blk + 8 )^kp[2]; + b0[3] = *( unsigned long * )( in_blk + 12 )^kp[3]; + kp += 4; + unsigned long b1[4]; + switch ( cx->Nrnd ) { + case 14: + b1[0] = kp[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + kp += 8; + case 12: + b1[0] = kp[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + kp += 8; + case 10: + b1[0] = kp[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 8 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 8 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 8 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 8 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 12 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 12 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 12 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 12 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 16 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 16 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 16 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 16 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 20 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 20 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 20 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 20 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 24 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 24 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 24 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 24 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 28 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 28 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 28 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 28 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b1[0] = ( kp + 32 )[0] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[1] = ( kp + 32 )[1] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b1[2] = ( kp + 32 )[2] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[3] = ( kp + 32 )[3] ^ ( rijndael_dec_it_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_dec_it_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_dec_it_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_dec_it_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b0[0] = ( kp + 36 )[0] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[1] = ( kp + 36 )[1] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b0[2] = ( kp + 36 )[2] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[3] = ( kp + 36 )[3] ^ ( rijndael_dec_il_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_dec_il_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_dec_il_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_dec_il_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + } + *( unsigned long * )out_blk = ( b0[0] ); + *( unsigned long * )( out_blk + 4 ) = ( b0[1] ); + *( unsigned long * )( out_blk + 8 ) = ( b0[2] ); + *( unsigned long * )( out_blk + 12 ) = ( b0[3] ); + return aes_good; +} + diff --git a/baseline/source/rijndael_dec/aes.h b/baseline/source/rijndael_dec/aes.h new file mode 100644 index 0000000..69bf3d3 --- /dev/null +++ b/baseline/source/rijndael_dec/aes.h @@ -0,0 +1,165 @@ +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + 1. FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of + 128 bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. + + 2. THE CIPHER INTERFACE + + byte (an unsigned 8-bit type) + word (an unsigned 32-bit type) + aes_ret: (a signed 16 bit type for function return values) + aes_good (value != 0, a good return) + aes_bad (value == 0, an error return) + enum aes_key: (encryption direction) + enc (set key for encryption) + dec (set key for decryption) + both (set key for both) + class or struct aes (structure for context) + + C subroutine calls: + + aes_ret set_blk(const word block_length, aes *cx) (variable block size) + aes_ret set_key(const byte key[], const word key_length, + const enum aes_key direction, aes *cx) + aes_ret encrypt(const byte input_blk[], byte output_blk[], const aes *cx) + aes_ret decrypt(const byte input_blk[], byte output_blk[], const aes *cx) + + IMPORTANT NOTE: If you are using this C interface and your compiler does + not set the memory used for objects to zero before use, you will need to + ensure that cx.mode is set to zero before using the C subroutine calls. + + The block length inputs to set_block and set_key are in numbers of + BYTES, not bits. The calls to subroutines must be made in the above + order but multiple calls can be made without repeating earlier calls + if their parameters have not changed. If the cipher block length is + variable but set_blk has not been called before cipher operations a + value of 16 is assumed (that is, the AES block size). In contrast to + earlier versions the block and key length parameters are now checked + for correctness and the encryption and decryption routines check to + ensure that an appropriate key has been set before they are called. + +*/ + +#ifndef _AES_H +#define _AES_H + +/* The only supported block size for the benchmark is 16 */ +#define BLOCK_SIZE 16 + +/* + The number of key schedule words for different block and key lengths + (allowing for the method of computation which requires the length to + be a multiple of the key length): + + Key Schedule key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 44 60 54 56 64 + length 20 | 60 60 66 70 80 + (bytes) 24 | 80 80 78 84 96 + 28 | 100 100 102 98 112 + 32 | 120 120 120 126 120 + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + The following values assume that the key length will be variable and may + be of maximum length (32 bytes). + + Nk = number_of_key_bytes / 4 + Nc = number_of_columns_in_state / 4 + Nr = number of encryption/decryption rounds + Rc = number of elements in rcon table + Ks = number of 32-bit words in key schedule +*/ + +#define Nr(Nk,Nc) ((Nk > Nc ? Nk : Nc) + 6) +#define Rc(Nk,Nc) ((Nb * (Nr(Nk,Nc) + 1) - 1) / Nk) +#define Ks(Nk,Nc) (Nk * (Rc(Nk,Nc) + 1)) + +#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11) +#define KS_LENGTH 4 * BLOCK_SIZE + +/* End of configuration options, but see also aes.c */ + +typedef unsigned char byte; /* must be an 8-bit storage unit */ +typedef unsigned long word; /* must be a 32-bit storage unit */ +typedef short aes_ret; /* function return value */ + +#define aes_bad 0 +#define aes_good 1 + +/* + upr(x,n): rotates bytes within words by n positions, moving bytes + to higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word +*/ + +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) +#define ups(x,n) ((x) << 8 * (n)) +#define bval(x,n) ((byte)((x) >> 8 * (n))) +#define byte_swap(x) (upr(x,1) & 0x00ff00ff | upr(x,3) & 0xff00ff00) +#define bytes2word(b0, b1, b2, b3) ((word)(b3) << 24 | (word)(b2) << 16 | \ + (word)(b1) << 8 | (b0)) + +#define word_in(x) *(word*)(x) +#define word_out(x,v) *(word*)(x) = (v) + +enum aes_const { Nrow = 4, /* the number of rows in the cipher state */ + Mcol = 8, /* maximum number of columns in the state */ + Ncol = BLOCK_SIZE / 4, + Shr0 = 0, /* the cyclic shift values for rows 0, 1, 2 & 3 */ + Shr1 = 1, + Shr2 = BLOCK_SIZE == 32 ? 3 : 2, + Shr3 = BLOCK_SIZE == 32 ? 4 : 3 + }; + +enum aes_key { enc = 1, /* set if encryption is needed */ + dec = 2, /* set if decryption is needed */ + both = 3 /* set if both are needed */ + }; + +struct aes { + word Nkey; /* the number of words in the key input block */ + word Nrnd; /* the number of cipher rounds */ + word e_key[KS_LENGTH]; /* the encryption key schedule */ + word d_key[KS_LENGTH]; /* the decryption key schedule */ + byte mode; /* encrypt, decrypt or both */ +}; + +aes_ret rijndael_dec_set_key( byte key[], const word n_bytes, + const enum aes_key f, struct aes *cx ); +aes_ret rijndael_dec_decrypt( const byte in_blk[], byte out_blk[], + const struct aes *cx ); + +#endif diff --git a/baseline/source/rijndael_dec/aestab.h b/baseline/source/rijndael_dec/aestab.h new file mode 100644 index 0000000..c42702b --- /dev/null +++ b/baseline/source/rijndael_dec/aestab.h @@ -0,0 +1,379 @@ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +/* + Used to ensure table is generated in the right format + depending on the internal byte order required. +*/ + +#define w0(p) 0x000000##p + +/* + Number of elements required in this table for different + block and key lengths is: + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + this table can be a table of bytes if the key schedule + code is adjusted accordingly +*/ + +const word rijndael_dec_rcon_tab[29] = { + w0( 01 ), w0( 02 ), w0( 04 ), w0( 08 ), + w0( 10 ), w0( 20 ), w0( 40 ), w0( 80 ), + w0( 1b ), w0( 36 ), w0( 6c ), w0( d8 ), + w0( ab ), w0( 4d ), w0( 9a ), w0( 2f ), + w0( 5e ), w0( bc ), w0( 63 ), w0( c6 ), + w0( 97 ), w0( 35 ), w0( 6a ), w0( d4 ), + w0( b3 ), w0( 7d ), w0( fa ), w0( ef ), + w0( c5 ) +}; + +#undef w0 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +#define r0(p,q,r,s) 0x##p##q##r##s +#define r1(p,q,r,s) 0x##q##r##s##p +#define r2(p,q,r,s) 0x##r##s##p##q +#define r3(p,q,r,s) 0x##s##p##q##r +#define w0(p) 0x000000##p +#define w1(p) 0x0000##p##00 +#define w2(p) 0x00##p##0000 +#define w3(p) 0x##p##000000 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +/* data for forward tables (other than last round) */ + +#define f_table \ + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6), \ + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91), \ + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56), \ + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec), \ + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa), \ + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb), \ + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45), \ + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b), \ + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c), \ + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83), \ + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9), \ + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a), \ + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d), \ + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f), \ + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df), \ + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea), \ + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34), \ + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b), \ + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d), \ + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13), \ + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1), \ + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6), \ + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72), \ + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85), \ + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed), \ + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11), \ + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe), \ + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b), \ + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05), \ + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1), \ + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42), \ + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf), \ + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3), \ + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e), \ + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a), \ + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6), \ + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3), \ + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b), \ + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28), \ + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad), \ + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14), \ + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8), \ + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4), \ + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2), \ + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da), \ + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49), \ + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf), \ + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10), \ + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c), \ + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97), \ + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e), \ + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f), \ + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc), \ + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c), \ + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69), \ + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27), \ + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22), \ + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33), \ + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9), \ + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5), \ + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a), \ + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0), \ + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e), \ + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) + +/* data for inverse tables (other than last round) */ + +#define i_table \ + r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a), \ + r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b), \ + r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5), \ + r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5), \ + r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d), \ + r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b), \ + r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95), \ + r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e), \ + r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27), \ + r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d), \ + r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62), \ + r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9), \ + r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52), \ + r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66), \ + r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3), \ + r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed), \ + r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e), \ + r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4), \ + r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4), \ + r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd), \ + r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d), \ + r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60), \ + r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67), \ + r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79), \ + r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00), \ + r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c), \ + r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36), \ + r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24), \ + r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b), \ + r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c), \ + r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12), \ + r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14), \ + r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3), \ + r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b), \ + r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8), \ + r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84), \ + r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7), \ + r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77), \ + r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47), \ + r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22), \ + r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98), \ + r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f), \ + r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54), \ + r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82), \ + r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf), \ + r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db), \ + r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83), \ + r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef), \ + r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29), \ + r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35), \ + r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33), \ + r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17), \ + r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4), \ + r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46), \ + r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb), \ + r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d), \ + r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb), \ + r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a), \ + r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73), \ + r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78), \ + r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2), \ + r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff), \ + r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64), \ + r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0) + +/* generate the required tables in the desired endian format */ + +#undef r +#define r r0 +const word rijndael_dec_it_tab[4][256] = { + { i_table }, +#undef r +#define r r1 + { i_table }, +#undef r +#define r r2 + { i_table }, +#undef r +#define r r3 + { i_table } +}; + +/* data for inverse tables (last round) */ + +#define li_table \ + w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38), \ + w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb), \ + w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87), \ + w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb), \ + w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d), \ + w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e), \ + w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2), \ + w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25), \ + w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16), \ + w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92), \ + w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da), \ + w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84), \ + w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a), \ + w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06), \ + w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02), \ + w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b), \ + w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea), \ + w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73), \ + w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85), \ + w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e), \ + w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89), \ + w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b), \ + w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20), \ + w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4), \ + w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31), \ + w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f), \ + w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d), \ + w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef), \ + w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0), \ + w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61), \ + w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26), \ + w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d), + +/* generate the required tables in the desired endian format */ + +#undef r +#define r(p,q,r,s) w0(q) +const word rijndael_dec_fl_tab[4][256] = { + { f_table }, +#undef r +#define r(p,q,r,s) w1(q) + { f_table }, +#undef r +#define r(p,q,r,s) w2(q) + { f_table }, +#undef r +#define r(p,q,r,s) w3(q) + { f_table } +}; + +#undef w +#define w w0 +const word rijndael_dec_il_tab[4][256] = { + { li_table }, +#undef w +#define w w1 + { li_table }, +#undef w +#define w w2 + { li_table }, +#undef w +#define w w3 + { li_table } +}; + +#define m_table \ + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12), \ + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a), \ + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62), \ + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a), \ + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2), \ + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca), \ + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82), \ + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba), \ + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9), \ + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1), \ + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9), \ + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81), \ + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29), \ + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11), \ + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59), \ + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61), \ + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf), \ + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87), \ + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf), \ + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7), \ + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f), \ + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67), \ + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f), \ + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17), \ + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64), \ + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c), \ + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14), \ + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c), \ + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84), \ + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc), \ + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4), \ + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc), \ + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53), \ + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b), \ + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23), \ + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b), \ + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3), \ + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b), \ + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3), \ + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb), \ + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88), \ + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0), \ + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8), \ + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0), \ + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68), \ + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50), \ + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18), \ + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20), \ + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe), \ + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6), \ + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e), \ + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6), \ + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e), \ + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26), \ + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e), \ + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56), \ + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25), \ + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d), \ + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55), \ + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d), \ + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5), \ + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd), \ + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5), \ + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d) + +#undef r +#define r r0 + +const word rijndael_dec_im_tab[4][256] = { + { m_table }, +#undef r +#define r r1 + { m_table }, +#undef r +#define r r2 + { m_table }, +#undef r +#define r r3 + { m_table } +}; diff --git a/baseline/source/rijndael_dec/input_small_enc.c b/baseline/source/rijndael_dec/input_small_enc.c new file mode 100644 index 0000000..2a881a9 --- /dev/null +++ b/baseline/source/rijndael_dec/input_small_enc.c @@ -0,0 +1,2051 @@ +unsigned char rijndael_dec_data[] = { + 96, 83, 127, 28, 212, 92, 146, 102, 38, 17, 193, 142, 95, 217, 184, 105, + 79, 112, 144, 112, 44, 202, 141, 48, 181, 177, 82, 92, 208, 250, 216, 152, + 41, 208, 7, 232, 238, 116, 134, 238, 230, 190, 239, 195, 235, 80, 125, 51, + 251, 39, 7, 100, 213, 190, 189, 81, 241, 49, 215, 254, 253, 203, 13, 164, + 175, 244, 25, 111, 226, 225, 176, 96, 58, 165, 32, 243, 68, 205, 209, 242, + 186, 229, 167, 155, 238, 105, 120, 173, 246, 72, 29, 96, 71, 169, 83, 154, + 226, 129, 236, 52, 243, 159, 61, 71, 20, 119, 245, 196, 25, 203, 11, 10, + 37, 163, 139, 180, 250, 191, 138, 99, 78, 192, 73, 186, 22, 12, 119, 151, + 185, 155, 195, 54, 73, 207, 108, 170, 112, 237, 100, 165, 219, 223, 23, 179, + 124, 172, 52, 22, 143, 57, 132, 60, 176, 218, 11, 86, 89, 59, 254, 84, + 180, 76, 120, 174, 17, 214, 88, 48, 240, 12, 56, 93, 136, 156, 75, 176, + 30, 43, 4, 107, 30, 210, 26, 183, 235, 39, 35, 205, 139, 80, 249, 182, + 15, 91, 210, 234, 47, 67, 64, 234, 148, 108, 240, 242, 32, 11, 48, 199, + 117, 31, 149, 30, 97, 149, 241, 50, 177, 166, 127, 31, 135, 115, 240, 77, + 198, 88, 108, 246, 108, 148, 158, 89, 173, 233, 252, 95, 51, 42, 218, 54, + 28, 143, 203, 164, 74, 147, 55, 108, 225, 222, 87, 161, 243, 35, 179, 130, + 29, 70, 225, 178, 148, 152, 247, 167, 21, 245, 84, 139, 3, 228, 221, 25, + 53, 36, 121, 29, 204, 35, 1, 46, 26, 8, 237, 102, 231, 252, 176, 88, + 24, 110, 255, 163, 86, 64, 117, 68, 178, 73, 219, 201, 24, 155, 76, 255, + 253, 199, 165, 95, 246, 179, 15, 47, 203, 81, 92, 231, 246, 247, 111, 58, + 82, 222, 193, 24, 37, 164, 161, 8, 169, 172, 223, 111, 186, 72, 160, 116, + 242, 8, 192, 178, 224, 177, 228, 42, 102, 206, 237, 52, 143, 16, 150, 143, + 108, 3, 88, 81, 199, 49, 110, 220, 5, 89, 244, 227, 27, 226, 101, 9, + 238, 0, 206, 228, 254, 19, 189, 240, 159, 29, 46, 2, 206, 184, 205, 228, + 144, 241, 88, 78, 156, 23, 44, 200, 99, 146, 179, 96, 1, 143, 87, 57, + 39, 75, 174, 32, 190, 125, 152, 183, 46, 39, 136, 88, 240, 110, 104, 70, + 253, 29, 110, 113, 235, 123, 56, 60, 243, 238, 246, 113, 11, 18, 246, 108, + 95, 238, 177, 43, 3, 112, 121, 161, 196, 204, 211, 171, 197, 41, 249, 71, + 194, 153, 82, 28, 10, 28, 12, 241, 212, 90, 124, 236, 171, 54, 35, 226, + 152, 246, 241, 74, 139, 133, 241, 76, 183, 197, 232, 250, 54, 202, 11, 10, + 203, 30, 169, 138, 110, 252, 62, 172, 6, 241, 81, 181, 87, 177, 128, 221, + 111, 133, 94, 251, 184, 54, 92, 242, 28, 112, 138, 116, 32, 164, 158, 59, + 51, 30, 155, 126, 196, 117, 233, 117, 92, 74, 4, 72, 19, 237, 248, 142, + 184, 175, 126, 203, 4, 210, 70, 40, 105, 16, 36, 42, 118, 110, 4, 180, + 208, 52, 232, 230, 107, 154, 233, 61, 176, 170, 32, 59, 60, 47, 43, 70, + 71, 3, 58, 24, 166, 22, 165, 154, 255, 166, 12, 81, 63, 116, 146, 12, + 5, 6, 133, 240, 110, 253, 209, 15, 71, 179, 93, 203, 58, 138, 5, 90, + 111, 140, 19, 186, 191, 68, 230, 121, 95, 166, 219, 107, 233, 156, 18, 145, + 239, 150, 234, 191, 91, 233, 114, 5, 215, 85, 30, 66, 33, 152, 117, 128, + 236, 189, 201, 203, 10, 184, 198, 249, 61, 27, 144, 102, 246, 191, 54, 129, + 86, 8, 197, 98, 231, 234, 222, 164, 161, 40, 150, 253, 208, 82, 92, 225, + 85, 206, 59, 1, 170, 5, 255, 219, 89, 204, 122, 169, 78, 8, 5, 70, + 75, 128, 80, 176, 16, 214, 253, 176, 255, 191, 91, 89, 126, 155, 128, 195, + 56, 150, 101, 131, 255, 234, 241, 250, 61, 210, 85, 19, 21, 23, 122, 180, + 34, 100, 102, 166, 128, 21, 177, 11, 86, 110, 112, 179, 126, 36, 152, 196, + 62, 185, 186, 20, 91, 35, 85, 148, 168, 68, 145, 245, 170, 25, 190, 237, + 192, 125, 186, 182, 22, 188, 161, 122, 194, 21, 14, 102, 206, 60, 129, 156, + 173, 176, 37, 112, 129, 145, 177, 101, 206, 179, 35, 221, 107, 228, 181, 212, + 52, 253, 241, 145, 121, 128, 68, 118, 78, 66, 166, 78, 176, 62, 217, 243, + 193, 1, 254, 200, 35, 67, 226, 77, 55, 72, 6, 144, 22, 85, 252, 209, + 142, 65, 226, 158, 126, 168, 175, 179, 219, 116, 235, 227, 42, 49, 126, 126, + 215, 200, 126, 0, 39, 247, 161, 217, 26, 228, 232, 113, 53, 151, 34, 223, + 91, 242, 155, 156, 144, 229, 237, 127, 227, 49, 239, 71, 102, 115, 74, 135, + 103, 13, 3, 108, 101, 211, 36, 59, 146, 143, 230, 44, 212, 145, 229, 53, + 108, 175, 42, 131, 113, 123, 30, 28, 149, 153, 117, 233, 76, 33, 148, 110, + 19, 83, 125, 135, 44, 202, 2, 155, 4, 240, 167, 7, 13, 115, 243, 216, + 73, 248, 216, 82, 230, 153, 48, 234, 157, 2, 130, 99, 147, 2, 244, 19, + 125, 30, 39, 148, 49, 134, 140, 240, 128, 230, 171, 24, 53, 245, 54, 72, + 111, 230, 192, 165, 199, 47, 186, 238, 121, 95, 220, 76, 229, 253, 157, 47, + 34, 47, 39, 77, 199, 203, 163, 148, 172, 56, 204, 96, 69, 235, 215, 96, + 92, 139, 92, 49, 73, 228, 70, 221, 18, 84, 167, 179, 201, 239, 71, 64, + 29, 247, 84, 56, 148, 36, 169, 144, 192, 60, 153, 171, 89, 125, 48, 98, + 201, 56, 230, 154, 146, 46, 184, 202, 3, 39, 113, 90, 249, 163, 0, 188, + 233, 10, 216, 17, 159, 42, 134, 57, 70, 24, 33, 63, 8, 67, 85, 7, + 133, 180, 127, 12, 234, 121, 183, 38, 131, 154, 241, 236, 69, 67, 116, 54, + 40, 225, 6, 220, 22, 251, 1, 100, 110, 165, 114, 12, 170, 21, 190, 103, + 242, 171, 216, 66, 30, 3, 214, 137, 231, 172, 61, 8, 249, 198, 113, 181, + 171, 13, 159, 21, 147, 67, 249, 94, 189, 174, 15, 2, 62, 254, 29, 32, + 209, 169, 184, 119, 220, 98, 248, 163, 171, 22, 62, 125, 155, 100, 186, 97, + 163, 245, 70, 216, 246, 1, 11, 83, 41, 100, 64, 52, 99, 184, 151, 99, + 46, 100, 168, 158, 210, 150, 38, 231, 27, 255, 59, 141, 232, 127, 56, 39, + 194, 104, 178, 151, 15, 25, 219, 221, 81, 119, 178, 153, 94, 173, 64, 215, + 128, 132, 163, 159, 214, 254, 181, 194, 113, 144, 141, 103, 17, 108, 178, 59, + 62, 205, 117, 57, 183, 97, 18, 210, 87, 163, 231, 213, 233, 251, 94, 136, + 217, 168, 69, 48, 55, 68, 144, 203, 187, 51, 211, 151, 1, 194, 118, 181, + 154, 103, 186, 87, 43, 128, 215, 79, 101, 175, 60, 221, 158, 189, 94, 194, + 87, 73, 72, 162, 252, 26, 40, 142, 86, 228, 82, 255, 122, 192, 167, 78, + 177, 40, 249, 195, 100, 188, 31, 208, 124, 123, 31, 121, 244, 4, 82, 3, + 132, 15, 2, 29, 186, 76, 106, 109, 158, 114, 25, 212, 74, 64, 255, 43, + 40, 146, 159, 225, 39, 65, 85, 37, 60, 160, 123, 116, 127, 134, 45, 177, + 191, 49, 136, 211, 167, 218, 197, 15, 96, 45, 55, 11, 237, 103, 118, 207, + 0, 211, 25, 143, 19, 93, 114, 90, 105, 253, 88, 140, 207, 56, 150, 0, + 136, 159, 134, 63, 75, 142, 177, 0, 107, 105, 78, 148, 214, 248, 70, 72, + 125, 220, 156, 220, 222, 102, 202, 176, 12, 58, 24, 39, 254, 170, 130, 77, + 203, 193, 162, 56, 162, 57, 76, 153, 170, 112, 94, 0, 220, 58, 58, 40, + 173, 2, 193, 164, 168, 127, 225, 238, 10, 194, 112, 213, 181, 126, 222, 152, + 12, 57, 14, 146, 137, 154, 203, 179, 45, 133, 70, 204, 66, 249, 32, 136, + 145, 0, 221, 224, 10, 1, 202, 139, 145, 247, 72, 254, 32, 169, 121, 167, + 114, 198, 244, 251, 243, 8, 114, 188, 178, 173, 25, 243, 122, 220, 45, 98, + 7, 168, 66, 58, 225, 217, 152, 81, 89, 39, 167, 146, 181, 138, 253, 196, + 145, 4, 72, 9, 14, 137, 155, 32, 217, 64, 4, 173, 220, 66, 114, 21, + 137, 118, 87, 163, 217, 204, 74, 236, 45, 170, 60, 141, 216, 234, 182, 79, + 74, 73, 94, 63, 89, 134, 88, 64, 32, 241, 9, 114, 253, 164, 108, 31, + 27, 42, 172, 7, 102, 213, 153, 83, 1, 152, 136, 224, 248, 70, 112, 15, + 211, 194, 216, 16, 255, 62, 83, 147, 173, 192, 239, 55, 18, 223, 34, 152, + 25, 163, 229, 4, 55, 219, 235, 187, 51, 116, 12, 202, 198, 116, 188, 217, + 91, 30, 11, 9, 13, 222, 120, 16, 93, 99, 56, 129, 27, 133, 155, 120, + 124, 112, 101, 42, 222, 122, 124, 59, 84, 228, 202, 189, 13, 11, 10, 44, + 220, 97, 67, 53, 246, 47, 230, 131, 192, 1, 247, 137, 90, 77, 243, 131, + 2, 130, 93, 183, 117, 102, 69, 191, 27, 87, 103, 218, 157, 124, 17, 209, + 135, 92, 78, 211, 141, 25, 157, 53, 17, 249, 209, 206, 84, 19, 135, 253, + 57, 36, 38, 112, 184, 61, 76, 5, 203, 155, 7, 9, 179, 167, 38, 136, + 189, 40, 19, 183, 132, 81, 135, 167, 48, 74, 186, 249, 144, 193, 150, 73, + 10, 192, 191, 160, 74, 246, 12, 38, 107, 3, 66, 122, 184, 168, 218, 233, + 78, 216, 11, 57, 124, 104, 167, 0, 187, 2, 214, 136, 252, 60, 85, 128, + 128, 31, 70, 197, 211, 180, 216, 75, 212, 163, 168, 15, 174, 44, 194, 231, + 24, 181, 154, 161, 241, 95, 197, 227, 146, 195, 187, 69, 127, 154, 145, 176, + 180, 157, 13, 225, 107, 60, 29, 14, 223, 93, 214, 248, 107, 65, 168, 251, + 231, 46, 34, 203, 76, 20, 206, 125, 80, 25, 196, 60, 213, 51, 238, 73, + 17, 223, 151, 44, 60, 213, 164, 117, 188, 66, 195, 170, 190, 117, 110, 21, + 27, 78, 244, 124, 224, 142, 182, 10, 122, 135, 121, 143, 240, 124, 6, 8, + 22, 15, 3, 137, 12, 19, 11, 62, 212, 205, 3, 202, 189, 157, 141, 68, + 171, 142, 106, 69, 207, 8, 116, 194, 6, 200, 96, 220, 248, 132, 46, 171, + 57, 234, 31, 3, 112, 108, 15, 139, 243, 34, 181, 250, 10, 86, 71, 162, + 167, 85, 177, 57, 166, 80, 41, 253, 128, 28, 127, 220, 149, 27, 29, 41, + 201, 116, 211, 236, 34, 200, 100, 157, 130, 223, 4, 162, 108, 181, 40, 255, + 96, 18, 77, 36, 217, 17, 225, 142, 124, 17, 91, 227, 13, 224, 213, 37, + 115, 216, 93, 149, 103, 105, 152, 190, 207, 54, 74, 226, 78, 133, 200, 252, + 157, 152, 39, 0, 173, 168, 132, 142, 17, 66, 241, 137, 12, 106, 42, 81, + 239, 78, 31, 131, 49, 243, 122, 178, 212, 137, 160, 104, 15, 145, 15, 116, + 103, 141, 94, 40, 127, 180, 174, 96, 222, 182, 226, 168, 174, 113, 228, 156, + 10, 18, 231, 122, 150, 178, 17, 200, 254, 96, 42, 243, 225, 58, 235, 64, + 159, 73, 162, 72, 46, 160, 33, 191, 99, 73, 130, 32, 135, 84, 29, 100, + 232, 75, 110, 180, 226, 11, 143, 127, 79, 246, 48, 148, 229, 211, 204, 72, + 18, 89, 22, 251, 202, 8, 10, 2, 130, 230, 219, 71, 66, 142, 149, 47, + 12, 117, 202, 224, 248, 35, 75, 242, 87, 125, 230, 66, 38, 160, 62, 248, + 213, 32, 166, 83, 220, 230, 0, 1, 147, 51, 128, 110, 20, 16, 43, 142, + 90, 0, 2, 104, 111, 232, 38, 29, 181, 243, 130, 121, 105, 177, 168, 113, + 126, 191, 59, 205, 27, 180, 49, 128, 160, 225, 23, 173, 193, 155, 123, 12, + 173, 72, 139, 63, 23, 232, 138, 235, 39, 179, 158, 95, 103, 192, 13, 242, + 11, 127, 239, 91, 13, 119, 19, 185, 105, 87, 195, 168, 145, 15, 53, 146, + 35, 227, 101, 234, 198, 247, 19, 29, 134, 126, 211, 133, 78, 186, 127, 129, + 181, 115, 133, 62, 166, 133, 128, 225, 101, 98, 146, 175, 110, 113, 171, 117, + 4, 130, 190, 186, 216, 17, 201, 29, 62, 77, 74, 189, 50, 155, 188, 93, + 237, 26, 100, 225, 91, 120, 229, 163, 16, 210, 167, 138, 241, 147, 36, 56, + 12, 100, 33, 55, 232, 200, 118, 3, 222, 31, 72, 167, 91, 45, 133, 62, + 184, 64, 120, 116, 249, 12, 15, 243, 98, 145, 234, 253, 71, 194, 61, 4, + 102, 112, 35, 27, 75, 13, 1, 4, 128, 238, 170, 187, 80, 147, 216, 165, + 147, 248, 250, 241, 69, 106, 233, 227, 22, 153, 120, 138, 113, 83, 104, 154, + 50, 99, 153, 188, 69, 252, 171, 177, 49, 74, 134, 219, 247, 255, 191, 202, + 165, 239, 179, 147, 91, 215, 195, 157, 68, 21, 180, 112, 187, 51, 66, 80, + 205, 100, 35, 78, 59, 92, 175, 87, 224, 170, 237, 223, 224, 83, 182, 199, + 47, 95, 111, 42, 197, 22, 21, 143, 123, 173, 69, 247, 31, 205, 69, 136, + 137, 136, 241, 233, 67, 7, 225, 112, 102, 92, 180, 211, 254, 29, 129, 29, + 21, 188, 44, 95, 57, 122, 17, 196, 213, 33, 56, 23, 88, 236, 185, 35, + 17, 156, 165, 93, 108, 157, 198, 5, 124, 225, 150, 156, 146, 116, 88, 116, + 181, 207, 90, 85, 145, 228, 231, 91, 116, 79, 6, 119, 6, 207, 190, 102, + 72, 242, 2, 253, 79, 92, 88, 189, 28, 57, 28, 101, 199, 134, 124, 215, + 59, 37, 222, 54, 194, 151, 252, 185, 74, 101, 193, 43, 186, 184, 255, 158, + 129, 183, 83, 176, 249, 134, 58, 15, 49, 213, 127, 162, 179, 56, 53, 4, + 114, 112, 29, 84, 246, 109, 46, 153, 97, 30, 208, 98, 234, 155, 104, 158, + 93, 9, 53, 175, 49, 54, 160, 238, 150, 117, 145, 202, 210, 37, 15, 3, + 100, 20, 116, 153, 90, 23, 2, 146, 58, 182, 199, 197, 122, 89, 30, 152, + 241, 105, 97, 115, 131, 111, 4, 235, 217, 213, 144, 218, 217, 201, 141, 113, + 21, 237, 254, 184, 181, 135, 177, 86, 215, 248, 169, 55, 231, 229, 60, 133, + 12, 194, 206, 112, 206, 175, 216, 131, 181, 41, 154, 235, 76, 152, 58, 118, + 111, 32, 220, 219, 253, 198, 18, 227, 71, 129, 197, 227, 96, 155, 66, 0, + 51, 132, 150, 208, 177, 188, 149, 100, 236, 23, 49, 45, 236, 131, 225, 206, + 77, 77, 94, 12, 244, 159, 85, 247, 189, 109, 141, 217, 80, 115, 44, 171, + 138, 68, 128, 147, 244, 213, 43, 187, 135, 126, 156, 158, 199, 61, 180, 112, + 130, 230, 146, 100, 106, 56, 70, 71, 234, 3, 202, 1, 45, 20, 136, 149, + 112, 178, 25, 110, 160, 221, 57, 191, 78, 9, 250, 233, 4, 144, 28, 219, + 200, 203, 227, 218, 229, 108, 59, 221, 141, 0, 122, 121, 65, 156, 204, 19, + 152, 215, 64, 164, 15, 77, 26, 113, 82, 229, 23, 103, 204, 151, 118, 104, + 171, 115, 72, 191, 5, 159, 133, 83, 221, 228, 120, 127, 46, 233, 14, 27, + 216, 31, 63, 179, 224, 226, 121, 29, 62, 47, 199, 67, 60, 240, 85, 175, + 242, 113, 168, 160, 93, 147, 205, 103, 67, 110, 237, 143, 148, 65, 209, 31, + 100, 252, 166, 254, 170, 52, 203, 222, 75, 219, 77, 217, 202, 18, 117, 253, + 92, 29, 205, 115, 53, 255, 251, 150, 164, 72, 146, 6, 101, 161, 127, 50, + 73, 152, 194, 180, 11, 121, 11, 229, 147, 151, 143, 226, 196, 238, 131, 141, + 173, 153, 189, 114, 16, 82, 1, 70, 239, 22, 85, 108, 113, 21, 231, 43, + 6, 228, 54, 94, 200, 186, 190, 143, 117, 156, 22, 30, 9, 64, 25, 8, + 116, 27, 240, 24, 150, 146, 224, 73, 97, 95, 183, 151, 185, 178, 16, 82, + 243, 208, 160, 186, 246, 234, 223, 35, 6, 166, 7, 105, 224, 246, 14, 208, + 1, 70, 244, 221, 238, 235, 86, 81, 136, 40, 99, 104, 89, 22, 194, 40, + 36, 45, 126, 138, 174, 22, 206, 228, 146, 114, 162, 4, 211, 213, 163, 224, + 91, 3, 85, 140, 140, 202, 204, 23, 194, 108, 166, 123, 1, 36, 191, 161, + 38, 228, 65, 249, 235, 26, 156, 83, 68, 199, 239, 109, 1, 203, 198, 25, + 22, 128, 165, 15, 125, 139, 190, 100, 184, 159, 16, 194, 244, 228, 18, 215, + 103, 169, 32, 208, 12, 104, 94, 71, 209, 193, 160, 161, 73, 38, 35, 49, + 202, 29, 193, 120, 100, 98, 219, 44, 27, 224, 222, 226, 105, 153, 17, 252, + 120, 143, 190, 173, 176, 89, 205, 149, 11, 99, 31, 107, 102, 187, 100, 107, + 200, 1, 130, 89, 75, 71, 196, 150, 89, 231, 28, 213, 173, 229, 173, 104, + 156, 123, 227, 163, 65, 230, 167, 67, 242, 143, 224, 224, 161, 249, 205, 140, + 149, 156, 2, 138, 177, 193, 136, 225, 177, 34, 246, 27, 179, 108, 116, 169, + 0, 183, 169, 12, 239, 230, 127, 169, 170, 144, 151, 36, 111, 52, 132, 2, + 15, 237, 209, 133, 254, 241, 184, 232, 116, 11, 221, 210, 64, 96, 18, 30, + 245, 95, 142, 84, 218, 92, 151, 20, 155, 101, 201, 153, 82, 163, 43, 168, + 152, 90, 224, 18, 112, 161, 123, 115, 129, 136, 198, 50, 186, 239, 28, 80, + 91, 20, 73, 6, 150, 187, 56, 54, 200, 67, 26, 62, 0, 229, 42, 210, + 107, 245, 83, 172, 233, 195, 140, 31, 24, 205, 202, 128, 145, 242, 73, 113, + 92, 176, 3, 146, 170, 21, 106, 67, 53, 254, 192, 212, 194, 6, 52, 81, + 163, 236, 63, 95, 164, 91, 60, 20, 9, 201, 74, 143, 55, 110, 76, 61, + 115, 177, 84, 105, 191, 199, 248, 51, 89, 35, 91, 44, 199, 13, 254, 130, + 142, 136, 64, 111, 128, 229, 171, 208, 183, 242, 195, 251, 72, 168, 31, 76, + 89, 102, 122, 181, 57, 110, 17, 196, 31, 136, 185, 196, 118, 100, 188, 100, + 21, 239, 206, 77, 97, 238, 78, 215, 224, 113, 210, 122, 141, 190, 103, 135, + 12, 41, 206, 157, 154, 10, 167, 133, 183, 60, 230, 235, 109, 33, 95, 121, + 34, 206, 1, 149, 114, 4, 252, 42, 17, 93, 191, 144, 133, 226, 101, 215, + 124, 88, 163, 27, 29, 189, 35, 51, 182, 112, 242, 94, 56, 196, 99, 242, + 77, 95, 123, 219, 81, 71, 229, 138, 101, 8, 77, 79, 2, 166, 195, 239, + 148, 221, 188, 20, 170, 26, 215, 139, 42, 171, 153, 219, 107, 191, 90, 185, + 241, 37, 84, 41, 232, 27, 123, 36, 86, 113, 255, 25, 245, 187, 21, 110, + 13, 17, 43, 99, 91, 182, 243, 239, 194, 150, 187, 111, 30, 83, 28, 111, + 249, 159, 212, 187, 184, 177, 12, 234, 107, 211, 32, 118, 132, 10, 145, 19, + 150, 206, 230, 158, 80, 101, 41, 67, 38, 79, 57, 164, 80, 147, 64, 207, + 231, 229, 162, 5, 185, 40, 164, 17, 84, 156, 1, 52, 181, 67, 63, 182, + 25, 68, 55, 167, 230, 125, 225, 234, 125, 79, 102, 35, 54, 2, 12, 145, + 67, 6, 252, 218, 231, 14, 58, 221, 248, 171, 23, 93, 14, 51, 76, 155, + 97, 239, 11, 95, 245, 154, 209, 127, 208, 19, 209, 158, 67, 164, 1, 123, + 230, 90, 236, 148, 77, 210, 240, 27, 154, 16, 146, 19, 107, 106, 141, 94, + 144, 28, 24, 130, 111, 164, 46, 108, 89, 171, 52, 192, 121, 188, 166, 207, + 164, 98, 57, 189, 54, 190, 18, 4, 120, 181, 18, 216, 162, 19, 111, 254, + 71, 171, 194, 79, 73, 122, 9, 115, 63, 61, 88, 117, 234, 203, 250, 167, + 102, 98, 101, 177, 5, 13, 228, 205, 115, 107, 219, 215, 33, 150, 13, 242, + 180, 71, 27, 0, 250, 228, 50, 129, 215, 93, 174, 169, 167, 125, 14, 89, + 130, 195, 127, 158, 250, 249, 142, 213, 5, 1, 250, 31, 122, 171, 62, 142, + 38, 84, 165, 95, 237, 144, 145, 189, 193, 248, 121, 112, 22, 11, 26, 192, + 90, 76, 117, 89, 160, 228, 152, 24, 129, 235, 37, 24, 66, 68, 161, 126, + 147, 44, 172, 137, 134, 203, 162, 152, 255, 161, 135, 6, 31, 72, 69, 9, + 228, 3, 80, 28, 50, 240, 176, 66, 255, 231, 21, 233, 149, 55, 211, 15, + 182, 116, 165, 211, 190, 28, 69, 40, 3, 164, 172, 212, 150, 181, 213, 32, + 174, 216, 8, 243, 29, 152, 124, 7, 111, 140, 53, 157, 158, 233, 175, 60, + 191, 179, 131, 248, 252, 50, 171, 165, 5, 51, 69, 215, 168, 222, 57, 221, + 164, 56, 193, 114, 18, 89, 219, 222, 198, 163, 200, 233, 28, 51, 190, 25, + 206, 243, 63, 51, 44, 10, 57, 71, 252, 230, 161, 141, 79, 31, 30, 150, + 101, 168, 23, 70, 216, 216, 160, 241, 192, 106, 92, 194, 141, 81, 100, 222, + 165, 180, 27, 70, 201, 219, 31, 177, 189, 114, 30, 74, 6, 184, 114, 208, + 189, 246, 83, 107, 229, 153, 69, 66, 201, 253, 183, 5, 134, 156, 200, 132, + 187, 73, 175, 213, 178, 14, 66, 101, 13, 224, 49, 205, 244, 124, 231, 18, + 71, 94, 246, 29, 78, 201, 138, 60, 97, 54, 156, 123, 144, 143, 6, 191, + 113, 140, 251, 203, 125, 196, 135, 169, 197, 34, 215, 77, 138, 218, 63, 56, + 145, 74, 225, 15, 227, 112, 113, 160, 165, 122, 85, 179, 97, 146, 5, 221, + 133, 236, 170, 2, 236, 128, 19, 252, 238, 120, 0, 192, 55, 5, 138, 161, + 222, 148, 189, 130, 53, 250, 36, 153, 248, 210, 197, 167, 236, 128, 191, 37, + 251, 151, 163, 190, 155, 38, 27, 164, 166, 238, 185, 11, 214, 212, 122, 206, + 212, 255, 103, 255, 69, 146, 54, 182, 52, 54, 169, 121, 244, 205, 244, 168, + 96, 163, 220, 75, 194, 10, 133, 204, 105, 10, 228, 139, 62, 39, 254, 131, + 5, 243, 54, 14, 158, 107, 118, 143, 81, 55, 251, 151, 226, 29, 54, 218, + 99, 187, 76, 178, 61, 206, 20, 170, 229, 190, 77, 215, 47, 104, 244, 87, + 101, 82, 50, 41, 255, 56, 6, 226, 22, 153, 19, 72, 227, 63, 224, 79, + 3, 130, 220, 135, 116, 39, 25, 98, 107, 50, 214, 183, 120, 215, 26, 160, + 247, 26, 190, 119, 146, 181, 147, 36, 15, 75, 109, 71, 72, 44, 14, 9, + 61, 201, 200, 222, 53, 246, 57, 69, 63, 108, 133, 140, 150, 33, 233, 46, + 84, 102, 150, 204, 129, 195, 97, 4, 69, 176, 166, 182, 10, 237, 141, 33, + 70, 200, 98, 101, 157, 9, 70, 227, 108, 195, 241, 72, 105, 86, 67, 5, + 242, 199, 149, 33, 43, 105, 206, 122, 20, 13, 28, 158, 131, 47, 202, 70, + 9, 92, 32, 10, 251, 103, 49, 185, 35, 242, 168, 151, 234, 237, 212, 91, + 81, 113, 133, 247, 204, 23, 4, 9, 226, 14, 29, 117, 236, 101, 250, 46, + 161, 149, 131, 98, 141, 228, 72, 18, 164, 252, 56, 7, 160, 217, 183, 125, + 121, 154, 169, 152, 211, 114, 24, 190, 141, 135, 41, 173, 250, 50, 54, 197, + 65, 67, 117, 246, 235, 130, 142, 138, 62, 216, 51, 193, 247, 30, 164, 235, + 209, 157, 138, 4, 147, 6, 253, 187, 34, 124, 1, 143, 60, 95, 168, 72, + 167, 72, 72, 13, 142, 35, 185, 107, 29, 51, 189, 48, 141, 194, 33, 77, + 118, 17, 80, 88, 204, 147, 148, 143, 103, 246, 97, 180, 153, 160, 112, 81, + 196, 2, 222, 148, 126, 240, 27, 61, 128, 155, 184, 106, 89, 36, 136, 230, + 128, 84, 217, 130, 139, 104, 115, 225, 73, 77, 7, 49, 183, 4, 250, 124, + 196, 34, 183, 209, 17, 136, 92, 16, 94, 51, 78, 174, 185, 117, 243, 69, + 11, 214, 132, 72, 86, 212, 4, 193, 253, 125, 45, 148, 97, 87, 6, 101, + 195, 169, 86, 115, 218, 254, 40, 59, 255, 137, 135, 183, 253, 117, 170, 29, + 191, 138, 247, 117, 125, 234, 30, 40, 92, 8, 180, 240, 136, 142, 111, 239, + 66, 225, 196, 151, 93, 130, 126, 255, 195, 34, 252, 17, 101, 179, 120, 76, + 4, 227, 13, 12, 66, 205, 235, 177, 29, 187, 25, 114, 68, 119, 114, 158, + 213, 149, 210, 5, 104, 71, 181, 126, 211, 32, 99, 60, 51, 75, 85, 138, + 138, 68, 115, 81, 37, 17, 101, 36, 117, 236, 182, 77, 98, 113, 198, 195, + 73, 79, 215, 116, 248, 45, 244, 60, 205, 35, 95, 228, 38, 180, 250, 246, + 63, 211, 44, 197, 162, 24, 195, 61, 136, 142, 91, 141, 62, 34, 139, 60, + 142, 238, 67, 148, 54, 132, 41, 115, 241, 219, 192, 121, 9, 45, 75, 183, + 223, 213, 165, 161, 219, 181, 161, 27, 36, 158, 163, 12, 12, 141, 83, 105, + 157, 118, 168, 244, 204, 32, 52, 131, 88, 246, 230, 121, 21, 58, 91, 217, + 138, 27, 251, 174, 150, 51, 240, 201, 30, 66, 19, 148, 185, 122, 53, 15, + 176, 144, 148, 3, 238, 59, 211, 155, 77, 83, 81, 245, 186, 169, 217, 201, + 103, 109, 137, 119, 146, 100, 18, 200, 185, 212, 202, 17, 88, 146, 234, 49, + 190, 19, 139, 43, 1, 48, 21, 64, 235, 89, 191, 74, 89, 85, 16, 64, + 203, 99, 152, 255, 61, 159, 36, 5, 199, 49, 94, 229, 163, 192, 41, 165, + 20, 203, 176, 149, 18, 152, 61, 216, 188, 203, 180, 103, 202, 176, 177, 210, + 255, 26, 254, 70, 43, 214, 95, 208, 73, 148, 124, 19, 215, 68, 123, 10, + 179, 88, 167, 224, 23, 246, 150, 201, 51, 157, 139, 187, 103, 187, 198, 189, + 204, 126, 74, 124, 23, 150, 108, 116, 196, 130, 92, 0, 211, 151, 19, 58, + 249, 50, 186, 54, 102, 164, 122, 228, 71, 163, 163, 117, 78, 234, 197, 70, + 96, 79, 4, 88, 242, 219, 120, 28, 178, 165, 136, 178, 129, 125, 79, 140, + 65, 62, 78, 237, 104, 11, 45, 191, 163, 145, 174, 23, 34, 240, 43, 137, + 102, 189, 140, 137, 4, 222, 55, 6, 84, 194, 51, 164, 107, 234, 39, 216, + 15, 12, 44, 86, 170, 121, 46, 4, 220, 200, 42, 53, 11, 228, 110, 187, + 116, 182, 242, 42, 93, 109, 47, 109, 180, 155, 31, 99, 60, 107, 114, 82, + 196, 146, 45, 224, 90, 205, 34, 200, 42, 173, 113, 37, 26, 154, 74, 18, + 165, 45, 22, 141, 1, 244, 64, 159, 164, 162, 100, 6, 67, 145, 199, 205, + 254, 149, 56, 138, 15, 172, 205, 203, 191, 253, 126, 238, 167, 210, 103, 33, + 143, 85, 161, 150, 99, 12, 207, 238, 110, 157, 190, 52, 249, 121, 139, 188, + 0, 74, 92, 106, 101, 254, 190, 251, 213, 167, 78, 36, 224, 24, 6, 195, + 128, 24, 21, 35, 66, 223, 204, 84, 177, 109, 226, 215, 79, 19, 236, 73, + 74, 244, 146, 57, 228, 254, 223, 158, 42, 83, 29, 181, 14, 147, 60, 4, + 147, 107, 95, 220, 180, 130, 140, 28, 118, 179, 39, 179, 250, 184, 27, 209, + 199, 151, 154, 121, 105, 81, 215, 143, 46, 91, 217, 94, 230, 250, 165, 21, + 240, 234, 93, 0, 176, 20, 127, 181, 36, 127, 49, 36, 79, 233, 229, 57, + 241, 56, 119, 151, 222, 239, 203, 217, 74, 164, 88, 47, 25, 43, 58, 136, + 61, 233, 70, 133, 181, 122, 250, 169, 249, 38, 36, 40, 182, 201, 40, 64, + 218, 145, 63, 209, 126, 248, 65, 23, 142, 147, 3, 241, 200, 87, 132, 93, + 31, 22, 90, 86, 244, 47, 235, 53, 187, 96, 165, 221, 185, 118, 134, 129, + 94, 64, 188, 132, 216, 198, 131, 74, 193, 32, 41, 194, 69, 201, 64, 31, + 6, 235, 95, 181, 207, 187, 60, 250, 24, 233, 127, 4, 5, 190, 242, 168, + 239, 185, 172, 78, 136, 121, 180, 191, 84, 54, 252, 83, 202, 111, 32, 100, + 213, 7, 178, 225, 71, 68, 244, 36, 141, 242, 199, 185, 71, 55, 244, 166, + 113, 41, 66, 177, 55, 251, 179, 251, 194, 2, 54, 20, 100, 241, 82, 213, + 236, 45, 196, 119, 134, 167, 163, 134, 61, 218, 207, 200, 118, 143, 249, 165, + 105, 78, 208, 213, 206, 72, 76, 123, 47, 31, 9, 234, 18, 125, 95, 170, + 199, 123, 139, 158, 244, 171, 6, 202, 240, 214, 94, 46, 60, 109, 185, 175, + 204, 176, 229, 110, 139, 249, 234, 3, 202, 231, 25, 195, 150, 136, 186, 246, + 72, 242, 133, 249, 229, 58, 112, 28, 228, 121, 85, 115, 90, 95, 32, 141, + 135, 217, 12, 187, 50, 229, 66, 103, 204, 0, 93, 86, 245, 59, 173, 28, + 71, 131, 135, 118, 125, 113, 12, 13, 202, 242, 205, 255, 152, 243, 160, 243, + 148, 10, 28, 106, 56, 17, 93, 234, 204, 102, 53, 22, 48, 188, 15, 255, + 14, 3, 117, 190, 211, 116, 55, 77, 205, 171, 228, 120, 244, 1, 169, 51, + 241, 150, 206, 99, 20, 68, 119, 137, 180, 44, 113, 85, 242, 143, 148, 97, + 149, 75, 20, 228, 89, 226, 122, 102, 13, 195, 58, 111, 178, 82, 226, 144, + 82, 237, 27, 94, 244, 29, 102, 32, 162, 80, 228, 66, 203, 107, 211, 171, + 4, 56, 62, 184, 63, 137, 5, 179, 231, 185, 172, 102, 190, 42, 80, 164, + 123, 68, 20, 36, 135, 97, 102, 156, 133, 165, 202, 240, 84, 168, 30, 95, + 57, 3, 182, 224, 10, 84, 60, 88, 191, 0, 126, 190, 240, 202, 141, 89, + 238, 212, 101, 213, 129, 15, 245, 94, 24, 49, 72, 59, 237, 121, 241, 199, + 28, 106, 113, 237, 82, 144, 150, 112, 79, 90, 255, 166, 230, 71, 132, 24, + 6, 82, 143, 150, 194, 236, 253, 46, 158, 143, 5, 31, 243, 156, 4, 19, + 89, 81, 94, 94, 39, 9, 199, 6, 44, 35, 4, 143, 18, 62, 27, 165, + 177, 162, 53, 121, 146, 74, 181, 252, 27, 207, 17, 102, 196, 172, 75, 4, + 17, 215, 20, 96, 9, 42, 199, 99, 206, 94, 78, 121, 37, 11, 152, 125, + 249, 107, 153, 180, 85, 155, 220, 68, 223, 87, 204, 175, 117, 147, 217, 71, + 6, 190, 132, 99, 227, 5, 180, 168, 249, 126, 202, 102, 42, 26, 175, 198, + 185, 211, 206, 154, 60, 24, 183, 24, 203, 46, 21, 176, 194, 116, 116, 210, + 162, 214, 215, 79, 87, 159, 16, 55, 12, 248, 51, 17, 79, 183, 145, 23, + 209, 58, 225, 84, 21, 237, 102, 250, 93, 222, 87, 87, 203, 4, 138, 196, + 6, 28, 143, 45, 68, 77, 211, 180, 47, 198, 5, 170, 166, 221, 107, 202, + 67, 220, 178, 156, 39, 2, 87, 147, 234, 85, 199, 97, 10, 151, 240, 121, + 229, 132, 230, 249, 244, 57, 77, 29, 123, 149, 121, 81, 245, 37, 106, 157, + 39, 185, 31, 175, 102, 187, 37, 149, 27, 215, 151, 155, 94, 160, 180, 59, + 95, 200, 149, 42, 178, 85, 171, 41, 31, 20, 16, 199, 14, 202, 230, 42, + 59, 83, 239, 155, 65, 63, 237, 89, 133, 62, 23, 112, 236, 226, 34, 250, + 134, 14, 234, 2, 212, 41, 135, 189, 114, 60, 147, 49, 19, 193, 169, 157, + 41, 62, 36, 42, 2, 172, 237, 250, 86, 252, 199, 80, 194, 195, 182, 136, + 209, 90, 80, 9, 121, 164, 168, 99, 235, 131, 129, 59, 26, 41, 124, 194, + 110, 143, 183, 126, 91, 50, 168, 211, 43, 177, 95, 196, 94, 206, 214, 173, + 89, 152, 173, 39, 53, 190, 186, 193, 75, 23, 181, 65, 153, 57, 142, 215, + 155, 147, 241, 110, 230, 102, 176, 152, 227, 83, 87, 110, 243, 143, 254, 127, + 254, 117, 117, 173, 106, 80, 127, 231, 39, 220, 178, 44, 95, 30, 60, 222, + 212, 72, 169, 84, 194, 40, 164, 156, 145, 182, 127, 51, 64, 108, 144, 124, + 136, 238, 4, 113, 14, 68, 106, 158, 20, 231, 109, 99, 70, 214, 68, 29, + 240, 154, 95, 206, 188, 136, 180, 41, 220, 228, 198, 82, 51, 118, 65, 20, + 198, 187, 22, 8, 134, 252, 86, 227, 110, 105, 198, 242, 48, 8, 192, 165, + 80, 210, 1, 175, 188, 99, 252, 178, 7, 70, 27, 249, 175, 145, 131, 228, + 86, 229, 81, 93, 203, 194, 226, 110, 250, 134, 235, 195, 170, 107, 131, 185, + 81, 99, 168, 124, 215, 108, 40, 198, 193, 117, 88, 136, 134, 114, 145, 239, + 9, 0, 184, 106, 111, 63, 6, 92, 30, 3, 116, 7, 232, 182, 184, 60, + 32, 161, 183, 167, 163, 185, 114, 43, 77, 134, 29, 164, 135, 3, 155, 255, + 83, 254, 203, 1, 243, 167, 236, 162, 77, 140, 250, 224, 25, 246, 81, 147, + 207, 0, 127, 115, 127, 151, 191, 179, 128, 77, 142, 203, 171, 153, 47, 244, + 165, 235, 20, 64, 36, 99, 201, 190, 83, 244, 125, 112, 49, 26, 95, 125, + 254, 140, 85, 142, 112, 170, 225, 4, 126, 243, 224, 180, 137, 152, 102, 9, + 92, 67, 247, 20, 189, 58, 88, 74, 183, 201, 43, 1, 2, 123, 228, 211, + 79, 91, 20, 64, 111, 238, 60, 76, 207, 91, 90, 130, 169, 238, 254, 208, + 125, 140, 7, 94, 63, 18, 46, 124, 16, 253, 228, 238, 179, 99, 129, 40, + 89, 12, 40, 42, 94, 237, 111, 112, 22, 162, 64, 25, 89, 102, 56, 25, + 245, 128, 221, 86, 146, 138, 242, 67, 166, 114, 204, 38, 89, 77, 127, 64, + 36, 183, 161, 254, 185, 76, 91, 10, 28, 146, 154, 254, 118, 200, 206, 95, + 6, 182, 35, 178, 179, 114, 87, 60, 208, 88, 180, 161, 171, 39, 156, 131, + 2, 83, 124, 11, 223, 57, 190, 18, 79, 245, 198, 11, 55, 131, 197, 28, + 74, 32, 223, 144, 231, 227, 25, 237, 243, 145, 64, 183, 62, 163, 33, 93, + 155, 82, 228, 206, 69, 77, 101, 8, 240, 3, 135, 0, 181, 153, 174, 82, + 29, 129, 40, 83, 235, 83, 98, 105, 235, 210, 121, 239, 78, 240, 217, 144, + 230, 225, 3, 157, 14, 118, 64, 228, 29, 110, 230, 247, 153, 117, 3, 81, + 24, 23, 169, 2, 247, 238, 144, 137, 241, 140, 192, 185, 165, 13, 122, 48, + 180, 254, 54, 128, 134, 247, 87, 42, 219, 166, 7, 248, 91, 39, 226, 245, + 44, 152, 30, 71, 125, 129, 102, 72, 16, 66, 119, 15, 189, 250, 70, 112, + 168, 7, 5, 181, 15, 114, 73, 112, 16, 184, 65, 192, 54, 51, 31, 202, + 38, 11, 170, 149, 37, 107, 44, 241, 30, 35, 23, 176, 99, 82, 230, 60, + 206, 39, 249, 227, 114, 152, 133, 233, 60, 188, 79, 52, 241, 191, 208, 160, + 213, 159, 219, 188, 222, 47, 235, 187, 9, 186, 112, 78, 101, 229, 115, 152, + 216, 196, 88, 228, 189, 226, 214, 40, 163, 155, 193, 238, 224, 72, 64, 199, + 4, 182, 248, 143, 219, 170, 227, 55, 215, 135, 92, 117, 56, 225, 220, 129, + 74, 226, 55, 132, 73, 213, 81, 93, 107, 49, 29, 155, 62, 141, 48, 190, + 242, 221, 95, 61, 179, 165, 213, 49, 125, 245, 106, 35, 24, 57, 103, 140, + 79, 172, 38, 29, 170, 145, 151, 204, 114, 161, 117, 2, 199, 145, 210, 184, + 71, 80, 251, 182, 67, 220, 3, 2, 210, 28, 17, 104, 68, 150, 255, 174, + 34, 206, 245, 97, 173, 8, 92, 160, 144, 149, 54, 57, 114, 145, 215, 115, + 186, 145, 165, 186, 207, 107, 14, 255, 88, 145, 225, 110, 190, 78, 93, 147, + 225, 247, 122, 52, 135, 147, 89, 3, 10, 119, 43, 154, 29, 186, 68, 50, + 125, 152, 205, 242, 113, 106, 80, 68, 21, 45, 147, 212, 5, 1, 27, 39, + 51, 221, 25, 38, 102, 67, 194, 250, 121, 51, 66, 76, 155, 205, 199, 54, + 177, 202, 0, 249, 225, 231, 179, 69, 52, 22, 87, 77, 193, 35, 88, 3, + 238, 62, 12, 159, 221, 203, 230, 122, 92, 71, 26, 218, 41, 218, 75, 21, + 201, 166, 224, 173, 110, 185, 97, 161, 227, 9, 43, 108, 162, 62, 228, 201, + 32, 178, 191, 115, 35, 118, 59, 165, 223, 135, 132, 230, 110, 213, 96, 68, + 190, 237, 213, 146, 85, 179, 242, 155, 122, 217, 7, 105, 70, 123, 10, 5, + 122, 153, 202, 218, 195, 207, 73, 175, 161, 31, 200, 47, 237, 64, 34, 227, + 34, 66, 58, 29, 28, 166, 242, 128, 33, 79, 32, 125, 60, 207, 222, 195, + 180, 137, 78, 177, 132, 249, 147, 38, 64, 247, 181, 81, 96, 155, 167, 113, + 95, 197, 30, 83, 18, 128, 93, 131, 242, 197, 50, 146, 106, 143, 56, 216, + 80, 80, 159, 164, 154, 220, 248, 193, 58, 253, 63, 219, 91, 140, 170, 71, + 152, 8, 69, 37, 138, 179, 223, 54, 98, 229, 181, 107, 50, 174, 6, 20, + 69, 101, 50, 57, 102, 61, 123, 218, 226, 77, 25, 129, 188, 103, 22, 81, + 66, 232, 19, 88, 103, 184, 87, 252, 109, 31, 242, 40, 37, 238, 237, 20, + 232, 170, 115, 36, 83, 127, 65, 208, 85, 56, 192, 120, 116, 153, 200, 116, + 108, 243, 110, 8, 9, 162, 206, 172, 25, 0, 103, 79, 239, 8, 184, 142, + 87, 86, 95, 139, 223, 180, 6, 205, 39, 76, 25, 62, 32, 244, 171, 152, + 146, 48, 224, 20, 23, 219, 250, 115, 159, 131, 14, 91, 5, 27, 26, 60, + 239, 5, 41, 159, 226, 103, 177, 43, 224, 51, 123, 129, 148, 18, 241, 66, + 192, 199, 151, 94, 207, 238, 120, 34, 234, 75, 193, 65, 66, 243, 125, 21, + 57, 113, 143, 44, 49, 153, 168, 129, 102, 21, 17, 101, 182, 217, 216, 17, + 7, 70, 99, 194, 34, 47, 49, 241, 25, 242, 163, 251, 28, 172, 167, 4, + 96, 213, 236, 60, 223, 52, 150, 216, 168, 157, 5, 56, 126, 50, 228, 130, + 166, 54, 196, 85, 86, 162, 154, 82, 84, 34, 228, 235, 157, 230, 47, 77, + 151, 127, 226, 82, 145, 205, 201, 40, 49, 178, 228, 77, 132, 208, 93, 4, + 2, 73, 46, 69, 188, 60, 130, 217, 1, 97, 177, 240, 18, 26, 141, 97, + 5, 170, 82, 56, 218, 83, 3, 29, 228, 13, 179, 232, 154, 50, 152, 40, + 58, 0, 202, 195, 36, 91, 104, 37, 10, 89, 0, 250, 146, 45, 248, 68, + 37, 180, 129, 46, 138, 43, 98, 40, 122, 174, 147, 85, 94, 255, 76, 129, + 245, 135, 198, 206, 144, 189, 190, 207, 253, 191, 104, 163, 141, 116, 1, 192, + 200, 193, 205, 196, 151, 231, 254, 190, 17, 172, 254, 196, 243, 72, 234, 236, + 92, 108, 153, 184, 39, 201, 109, 233, 38, 178, 163, 46, 150, 153, 170, 238, + 84, 196, 155, 171, 31, 3, 186, 55, 87, 100, 179, 61, 163, 119, 82, 75, + 107, 173, 8, 145, 135, 226, 243, 8, 38, 102, 123, 120, 169, 215, 177, 132, + 111, 26, 242, 205, 150, 143, 197, 152, 137, 193, 174, 171, 234, 183, 221, 189, + 40, 212, 191, 137, 47, 153, 85, 76, 59, 255, 16, 51, 186, 105, 224, 14, + 73, 41, 84, 42, 12, 186, 198, 133, 82, 8, 161, 173, 130, 25, 26, 22, + 152, 132, 221, 182, 68, 126, 160, 248, 183, 112, 129, 83, 181, 55, 17, 145, + 18, 220, 143, 17, 49, 18, 15, 191, 104, 40, 67, 139, 127, 106, 56, 65, + 4, 120, 100, 5, 88, 44, 82, 240, 138, 64, 42, 158, 24, 130, 133, 237, + 235, 112, 115, 164, 249, 247, 233, 173, 116, 245, 23, 37, 216, 180, 118, 183, + 58, 246, 254, 103, 93, 55, 36, 213, 76, 134, 122, 116, 164, 15, 11, 115, + 168, 185, 226, 79, 250, 236, 172, 24, 226, 48, 150, 67, 128, 63, 211, 235, + 219, 120, 216, 18, 31, 82, 136, 105, 151, 118, 193, 43, 33, 155, 55, 8, + 17, 3, 211, 110, 115, 27, 122, 3, 195, 97, 1, 227, 22, 124, 213, 59, + 89, 13, 253, 221, 207, 229, 25, 72, 200, 144, 209, 147, 185, 68, 132, 104, + 7, 34, 237, 45, 2, 17, 209, 87, 170, 227, 60, 230, 53, 186, 59, 39, + 254, 57, 191, 201, 59, 202, 119, 144, 163, 255, 78, 199, 9, 59, 129, 64, + 232, 31, 20, 110, 63, 172, 85, 239, 97, 216, 252, 158, 76, 64, 55, 133, + 43, 101, 22, 4, 27, 134, 210, 9, 120, 44, 255, 105, 142, 83, 6, 238, + 61, 226, 118, 111, 217, 234, 153, 48, 9, 193, 133, 172, 20, 121, 210, 40, + 243, 49, 13, 184, 152, 126, 248, 100, 37, 187, 216, 15, 250, 86, 178, 24, + 30, 174, 216, 151, 139, 27, 166, 190, 200, 228, 25, 152, 212, 70, 7, 45, + 141, 54, 143, 106, 206, 49, 170, 195, 61, 24, 81, 20, 116, 147, 95, 49, + 245, 179, 223, 237, 184, 110, 49, 158, 190, 211, 132, 30, 22, 195, 234, 167, + 143, 4, 26, 9, 215, 48, 100, 53, 221, 177, 172, 132, 184, 229, 165, 207, + 213, 192, 26, 58, 211, 227, 65, 148, 198, 5, 248, 169, 32, 121, 24, 164, + 193, 137, 218, 218, 105, 42, 136, 146, 91, 72, 238, 231, 24, 17, 108, 194, + 206, 5, 180, 101, 199, 161, 172, 130, 78, 110, 255, 62, 158, 111, 204, 223, + 33, 183, 43, 10, 93, 253, 249, 193, 149, 89, 21, 51, 198, 186, 91, 142, + 121, 157, 35, 254, 21, 55, 2, 7, 119, 32, 175, 107, 199, 86, 174, 37, + 144, 192, 13, 234, 244, 152, 150, 77, 69, 91, 174, 141, 211, 71, 85, 190, + 231, 124, 80, 80, 137, 195, 5, 196, 21, 239, 110, 92, 99, 158, 247, 229, + 178, 99, 156, 222, 135, 119, 197, 242, 98, 58, 0, 134, 97, 197, 30, 113, + 164, 183, 9, 1, 97, 166, 94, 117, 183, 103, 45, 147, 215, 137, 8, 64, + 9, 149, 66, 130, 166, 94, 72, 48, 181, 156, 233, 167, 116, 59, 10, 117, + 203, 53, 110, 133, 3, 97, 84, 60, 179, 90, 47, 45, 78, 41, 89, 191, + 234, 81, 129, 69, 179, 76, 221, 176, 171, 58, 158, 151, 251, 79, 189, 124, + 159, 40, 189, 229, 126, 168, 24, 141, 209, 215, 105, 170, 166, 181, 113, 36, + 4, 172, 90, 123, 232, 154, 150, 224, 87, 249, 134, 136, 14, 28, 23, 67, + 78, 187, 209, 55, 157, 95, 36, 136, 83, 103, 54, 236, 62, 81, 66, 44, + 85, 120, 219, 178, 62, 126, 203, 193, 229, 146, 25, 187, 254, 141, 147, 185, + 158, 103, 216, 216, 38, 34, 245, 43, 169, 200, 129, 130, 7, 239, 207, 155, + 250, 89, 209, 238, 20, 74, 133, 100, 67, 149, 41, 187, 72, 9, 135, 165, + 140, 14, 90, 51, 241, 216, 7, 176, 238, 254, 84, 53, 231, 87, 12, 51, + 222, 54, 70, 163, 101, 130, 63, 37, 120, 180, 219, 161, 69, 213, 233, 130, + 199, 124, 2, 36, 224, 140, 95, 201, 23, 72, 219, 222, 181, 237, 134, 11, + 103, 94, 246, 251, 215, 218, 228, 90, 36, 54, 237, 49, 204, 13, 194, 221, + 18, 186, 35, 144, 179, 2, 98, 90, 110, 165, 66, 38, 152, 206, 0, 121, + 90, 25, 94, 145, 133, 58, 143, 138, 175, 80, 233, 110, 78, 84, 0, 207, + 87, 78, 27, 243, 160, 231, 241, 83, 173, 163, 191, 205, 184, 216, 232, 36, + 194, 52, 5, 72, 249, 42, 103, 254, 213, 41, 159, 209, 56, 222, 40, 224, + 177, 195, 214, 11, 84, 221, 245, 137, 131, 23, 220, 251, 167, 17, 34, 214, + 41, 102, 226, 223, 79, 53, 119, 84, 17, 219, 19, 80, 90, 132, 19, 176, + 73, 145, 38, 28, 198, 176, 141, 92, 242, 69, 174, 63, 244, 44, 152, 102, + 120, 151, 167, 115, 67, 110, 119, 159, 56, 63, 29, 70, 253, 118, 119, 220, + 181, 71, 193, 167, 77, 178, 236, 187, 193, 236, 147, 231, 209, 56, 168, 202, + 7, 198, 208, 17, 20, 31, 42, 70, 237, 148, 162, 161, 128, 135, 88, 37, + 219, 56, 83, 248, 116, 20, 44, 17, 231, 156, 187, 251, 237, 165, 123, 165, + 181, 166, 212, 99, 132, 26, 122, 240, 223, 130, 235, 248, 239, 11, 161, 32, + 109, 210, 97, 173, 12, 251, 94, 118, 7, 107, 206, 105, 158, 16, 4, 245, + 159, 67, 150, 226, 53, 42, 241, 249, 146, 107, 111, 75, 147, 136, 141, 97, + 49, 101, 233, 168, 197, 72, 95, 138, 162, 103, 154, 162, 192, 78, 41, 102, + 52, 207, 165, 48, 93, 41, 104, 136, 91, 169, 167, 51, 217, 197, 25, 238, + 3, 4, 35, 64, 146, 153, 32, 107, 66, 225, 249, 148, 225, 130, 197, 194, + 34, 100, 235, 200, 204, 39, 230, 37, 103, 219, 139, 8, 232, 63, 95, 154, + 76, 195, 226, 187, 206, 116, 21, 40, 98, 177, 244, 9, 114, 148, 22, 185, + 243, 93, 8, 84, 137, 114, 217, 240, 69, 185, 123, 1, 225, 160, 221, 183, + 81, 159, 31, 66, 221, 201, 197, 113, 137, 181, 249, 211, 211, 226, 62, 12, + 116, 111, 130, 197, 99, 85, 29, 191, 94, 14, 166, 137, 147, 14, 133, 58, + 230, 148, 144, 87, 48, 117, 252, 64, 114, 18, 185, 63, 164, 159, 26, 79, + 188, 242, 126, 223, 213, 245, 195, 144, 19, 68, 175, 73, 15, 90, 45, 245, + 111, 212, 15, 108, 108, 199, 180, 231, 92, 251, 69, 251, 100, 179, 160, 125, + 250, 42, 79, 118, 101, 195, 108, 15, 243, 124, 76, 248, 137, 80, 49, 16, + 233, 89, 247, 188, 102, 212, 82, 111, 184, 67, 70, 110, 79, 241, 15, 157, + 225, 66, 87, 81, 35, 200, 210, 21, 243, 196, 86, 48, 46, 152, 150, 236, + 76, 45, 178, 131, 90, 85, 147, 107, 25, 194, 182, 106, 191, 161, 71, 94, + 211, 172, 93, 128, 17, 188, 240, 127, 4, 18, 124, 199, 122, 163, 140, 228, + 91, 163, 59, 197, 191, 231, 162, 77, 248, 24, 168, 119, 182, 169, 140, 55, + 207, 105, 70, 81, 32, 79, 212, 1, 59, 11, 55, 145, 61, 90, 134, 202, + 49, 105, 117, 158, 91, 86, 139, 55, 90, 171, 167, 237, 141, 1, 184, 49, + 63, 7, 226, 53, 153, 200, 188, 224, 234, 104, 101, 118, 238, 93, 34, 252, + 120, 251, 177, 103, 213, 173, 184, 231, 225, 111, 186, 210, 40, 111, 65, 4, + 60, 124, 221, 67, 201, 210, 65, 90, 74, 36, 39, 88, 233, 64, 172, 179, + 18, 59, 182, 82, 152, 192, 154, 220, 209, 184, 218, 210, 172, 250, 155, 199, + 175, 246, 218, 45, 211, 204, 131, 204, 73, 107, 246, 52, 133, 102, 103, 135, + 5, 46, 175, 63, 204, 92, 108, 126, 126, 194, 208, 178, 166, 198, 191, 240, + 128, 5, 203, 189, 102, 148, 65, 29, 146, 2, 24, 21, 201, 147, 145, 248, + 85, 77, 63, 245, 176, 199, 198, 237, 34, 101, 159, 144, 166, 29, 102, 175, + 121, 78, 75, 196, 204, 80, 156, 236, 198, 232, 117, 112, 135, 61, 63, 63, + 82, 2, 65, 139, 70, 69, 78, 64, 48, 154, 15, 250, 79, 190, 251, 94, + 205, 252, 236, 241, 2, 171, 232, 118, 128, 71, 18, 55, 49, 13, 27, 36, + 149, 220, 149, 150, 55, 200, 192, 151, 47, 218, 134, 205, 93, 7, 206, 44, + 229, 208, 62, 208, 55, 55, 239, 63, 45, 154, 171, 70, 223, 144, 78, 251, + 5, 138, 224, 21, 184, 87, 55, 69, 224, 231, 37, 65, 87, 114, 78, 216, + 41, 49, 143, 233, 182, 214, 84, 20, 20, 156, 17, 12, 173, 172, 80, 151, + 37, 28, 191, 69, 146, 102, 65, 15, 152, 143, 198, 45, 204, 4, 140, 90, + 149, 45, 157, 190, 119, 196, 121, 199, 176, 122, 198, 141, 161, 31, 24, 149, + 96, 231, 70, 122, 160, 19, 100, 75, 112, 141, 18, 175, 109, 98, 19, 110, + 237, 1, 5, 171, 153, 19, 251, 61, 180, 249, 9, 187, 196, 248, 127, 13, + 21, 244, 224, 42, 97, 40, 236, 190, 18, 123, 133, 26, 235, 9, 150, 90, + 21, 189, 189, 101, 226, 190, 82, 18, 45, 3, 172, 187, 72, 74, 244, 211, + 76, 2, 70, 168, 41, 195, 165, 178, 139, 5, 155, 100, 199, 0, 227, 72, + 247, 186, 33, 169, 34, 104, 196, 3, 253, 202, 19, 140, 100, 122, 144, 125, + 201, 202, 194, 245, 180, 27, 10, 207, 180, 31, 25, 152, 243, 143, 51, 90, + 33, 74, 147, 127, 66, 47, 10, 65, 99, 71, 243, 241, 221, 219, 32, 213, + 98, 67, 119, 130, 254, 11, 149, 64, 73, 168, 73, 237, 110, 18, 243, 21, + 177, 53, 109, 2, 242, 89, 136, 34, 36, 135, 12, 12, 125, 251, 104, 137, + 128, 152, 41, 70, 163, 184, 237, 137, 249, 63, 56, 133, 39, 0, 243, 248, + 80, 184, 48, 238, 155, 193, 21, 137, 95, 144, 146, 209, 151, 197, 199, 122, + 60, 48, 250, 1, 79, 162, 58, 78, 225, 184, 199, 35, 186, 225, 19, 68, + 31, 199, 150, 85, 197, 76, 246, 150, 47, 63, 55, 196, 200, 10, 163, 170, + 246, 34, 196, 87, 0, 45, 18, 6, 168, 248, 130, 184, 5, 197, 97, 56, + 128, 254, 236, 32, 10, 182, 198, 139, 255, 43, 41, 159, 119, 253, 81, 248, + 251, 253, 184, 98, 229, 6, 8, 64, 48, 190, 105, 125, 168, 191, 43, 93, + 156, 39, 244, 220, 138, 197, 117, 27, 152, 145, 254, 233, 211, 33, 234, 5, + 72, 247, 49, 221, 35, 188, 210, 20, 231, 90, 255, 37, 30, 126, 209, 65, + 137, 123, 126, 191, 158, 227, 201, 129, 19, 164, 51, 232, 188, 185, 96, 67, + 24, 190, 56, 16, 229, 34, 219, 150, 137, 226, 59, 58, 3, 147, 232, 35, + 99, 207, 101, 173, 217, 18, 139, 1, 94, 123, 4, 232, 147, 243, 13, 193, + 193, 187, 232, 100, 187, 119, 105, 72, 86, 30, 165, 20, 192, 19, 157, 67, + 253, 204, 246, 133, 85, 252, 109, 169, 106, 203, 83, 72, 51, 217, 172, 7, + 212, 104, 170, 166, 21, 181, 11, 14, 145, 33, 175, 235, 169, 66, 203, 78, + 108, 209, 100, 131, 93, 192, 70, 157, 186, 224, 174, 173, 22, 167, 87, 244, + 227, 218, 96, 98, 186, 24, 205, 62, 66, 79, 198, 254, 160, 37, 127, 16, + 95, 171, 47, 34, 80, 43, 26, 111, 65, 207, 29, 139, 135, 69, 13, 110, + 133, 110, 65, 140, 61, 207, 117, 98, 106, 29, 166, 224, 78, 208, 252, 194, + 91, 4, 38, 0, 61, 133, 180, 168, 149, 211, 7, 80, 227, 135, 51, 11, + 249, 228, 26, 198, 244, 2, 47, 226, 93, 147, 222, 125, 200, 205, 166, 154, + 234, 80, 39, 70, 84, 98, 209, 1, 6, 219, 17, 11, 253, 126, 145, 231, + 131, 14, 163, 107, 200, 195, 167, 64, 6, 101, 209, 255, 116, 179, 69, 164, + 133, 23, 78, 98, 105, 182, 236, 34, 246, 58, 81, 183, 100, 30, 44, 187, + 164, 91, 239, 132, 51, 154, 9, 2, 215, 186, 191, 79, 237, 179, 141, 169, + 237, 206, 190, 201, 64, 223, 143, 60, 173, 108, 96, 216, 183, 70, 110, 5, + 59, 230, 206, 194, 40, 211, 109, 146, 1, 102, 194, 212, 90, 214, 43, 111, + 134, 122, 146, 9, 220, 198, 72, 196, 68, 19, 214, 220, 11, 173, 243, 15, + 254, 158, 193, 211, 191, 55, 163, 212, 18, 20, 42, 199, 191, 74, 238, 191, + 113, 173, 125, 203, 48, 1, 119, 32, 224, 8, 178, 179, 0, 67, 153, 62, + 227, 25, 254, 126, 23, 87, 67, 43, 45, 250, 42, 214, 118, 179, 111, 189, + 103, 133, 35, 196, 54, 23, 203, 218, 59, 177, 194, 55, 210, 153, 78, 207, + 145, 157, 229, 119, 218, 173, 20, 104, 251, 48, 204, 245, 166, 251, 123, 82, + 175, 239, 215, 158, 200, 1, 174, 40, 200, 32, 108, 184, 0, 137, 90, 81, + 159, 128, 165, 10, 233, 210, 52, 48, 74, 164, 246, 199, 240, 154, 12, 254, + 70, 37, 106, 44, 85, 123, 151, 119, 153, 170, 48, 144, 241, 114, 64, 115, + 120, 159, 13, 49, 211, 182, 99, 124, 25, 70, 73, 196, 179, 201, 219, 124, + 22, 137, 229, 160, 155, 10, 158, 234, 132, 203, 208, 76, 81, 98, 30, 142, + 154, 68, 158, 92, 107, 252, 4, 22, 218, 2, 167, 190, 152, 141, 251, 137, + 236, 87, 186, 235, 90, 0, 132, 68, 232, 66, 63, 0, 41, 235, 157, 45, + 68, 194, 45, 18, 249, 254, 60, 33, 10, 86, 183, 45, 5, 253, 253, 212, + 44, 94, 203, 41, 53, 146, 101, 148, 123, 198, 92, 14, 181, 87, 49, 229, + 177, 249, 216, 8, 12, 37, 108, 220, 236, 13, 72, 122, 48, 235, 219, 74, + 220, 187, 130, 66, 249, 41, 184, 140, 101, 1, 203, 110, 22, 62, 23, 118, + 199, 32, 191, 162, 140, 187, 157, 80, 144, 59, 112, 238, 32, 101, 238, 47, + 225, 69, 99, 178, 246, 49, 76, 81, 101, 187, 71, 59, 140, 229, 81, 253, + 42, 204, 158, 74, 184, 237, 197, 14, 91, 81, 34, 115, 123, 224, 167, 15, + 112, 84, 225, 104, 103, 208, 236, 183, 185, 142, 175, 147, 237, 188, 159, 125, + 142, 253, 121, 87, 239, 78, 57, 179, 13, 123, 74, 148, 197, 74, 227, 110, + 48, 248, 165, 248, 249, 43, 249, 0, 69, 7, 183, 68, 167, 181, 39, 54, + 144, 39, 212, 36, 40, 171, 48, 106, 76, 50, 201, 111, 254, 86, 240, 39, + 14, 59, 58, 110, 54, 155, 2, 6, 205, 190, 237, 126, 58, 204, 112, 159, + 145, 188, 208, 196, 197, 52, 54, 94, 84, 127, 46, 56, 93, 152, 190, 133, + 120, 166, 75, 52, 6, 112, 112, 71, 119, 143, 218, 19, 242, 174, 48, 246, + 29, 243, 137, 94, 127, 95, 76, 49, 20, 149, 159, 251, 59, 146, 102, 242, + 222, 157, 162, 124, 154, 25, 47, 246, 135, 38, 177, 165, 246, 224, 202, 4, + 177, 255, 203, 245, 58, 172, 164, 33, 155, 179, 56, 41, 202, 39, 145, 176, + 130, 171, 30, 77, 177, 64, 203, 70, 230, 242, 240, 118, 145, 30, 89, 184, + 11, 123, 157, 212, 156, 28, 5, 200, 96, 157, 102, 126, 212, 149, 137, 144, + 169, 39, 211, 159, 193, 254, 65, 201, 154, 165, 37, 129, 14, 242, 28, 37, + 17, 130, 202, 227, 241, 49, 191, 213, 179, 72, 243, 118, 52, 133, 149, 8, + 156, 231, 94, 215, 15, 21, 118, 194, 254, 107, 249, 40, 153, 69, 95, 141, + 97, 37, 224, 82, 146, 71, 35, 26, 88, 127, 137, 247, 242, 243, 135, 113, + 189, 155, 56, 98, 99, 90, 108, 186, 118, 178, 253, 50, 44, 30, 43, 223, + 171, 186, 44, 120, 215, 128, 45, 65, 178, 142, 159, 39, 70, 37, 168, 62, + 127, 219, 111, 40, 239, 134, 47, 114, 69, 45, 87, 15, 234, 100, 9, 90, + 220, 203, 241, 40, 150, 239, 164, 39, 164, 196, 117, 156, 132, 143, 87, 146, + 190, 130, 168, 244, 193, 101, 110, 158, 231, 57, 146, 235, 227, 8, 12, 208, + 209, 203, 35, 38, 242, 45, 43, 118, 252, 201, 244, 130, 42, 18, 133, 66, + 129, 209, 77, 208, 69, 236, 138, 254, 255, 245, 112, 236, 86, 171, 1, 111, + 107, 69, 213, 222, 232, 199, 49, 193, 174, 198, 100, 170, 183, 150, 10, 233, + 28, 210, 219, 123, 233, 126, 105, 75, 222, 231, 13, 137, 242, 177, 41, 137, + 60, 202, 92, 16, 131, 226, 193, 152, 79, 95, 235, 105, 227, 172, 7, 160, + 180, 146, 190, 243, 34, 19, 186, 215, 106, 95, 152, 49, 90, 68, 71, 90, + 222, 240, 72, 16, 153, 69, 114, 193, 215, 175, 165, 224, 198, 154, 70, 104, + 79, 97, 153, 54, 153, 179, 2, 207, 197, 243, 12, 159, 76, 168, 136, 217, + 116, 79, 104, 21, 215, 72, 199, 35, 153, 67, 50, 145, 11, 253, 62, 254, + 121, 1, 8, 147, 39, 20, 94, 155, 80, 41, 135, 135, 45, 85, 61, 140, + 26, 195, 80, 187, 252, 175, 253, 152, 170, 169, 118, 235, 158, 134, 82, 188, + 86, 52, 70, 32, 239, 212, 157, 115, 137, 28, 191, 156, 197, 136, 226, 171, + 17, 231, 181, 79, 246, 232, 178, 242, 233, 113, 210, 230, 35, 201, 213, 28, + 72, 27, 183, 26, 106, 240, 111, 111, 255, 122, 128, 234, 179, 201, 66, 165, + 245, 198, 201, 138, 20, 212, 139, 159, 200, 91, 150, 175, 209, 203, 255, 81, + 30, 27, 83, 216, 119, 36, 48, 112, 237, 229, 175, 204, 149, 192, 183, 184, + 165, 176, 231, 176, 223, 81, 214, 225, 145, 107, 248, 225, 213, 6, 99, 59, + 197, 183, 125, 208, 26, 19, 178, 146, 154, 242, 71, 189, 11, 246, 48, 8, + 7, 28, 105, 208, 20, 13, 236, 77, 244, 218, 101, 217, 125, 199, 153, 77, + 193, 214, 233, 91, 48, 201, 209, 6, 155, 87, 208, 221, 9, 73, 76, 191, + 23, 249, 237, 146, 189, 177, 55, 8, 68, 192, 111, 204, 19, 164, 189, 223, + 83, 220, 156, 79, 12, 82, 178, 149, 102, 94, 120, 229, 198, 77, 136, 244, + 84, 33, 90, 66, 193, 45, 252, 160, 151, 66, 240, 135, 232, 147, 235, 107, + 173, 30, 184, 103, 131, 168, 55, 195, 111, 16, 202, 227, 203, 16, 14, 226, + 104, 220, 126, 121, 163, 5, 26, 253, 35, 196, 13, 90, 196, 32, 157, 28, + 152, 70, 205, 236, 101, 142, 207, 126, 230, 67, 194, 143, 67, 77, 91, 97, + 71, 135, 244, 40, 104, 120, 39, 169, 91, 124, 162, 111, 121, 9, 118, 146, + 215, 112, 120, 157, 22, 198, 241, 196, 32, 176, 60, 244, 197, 37, 210, 215, + 125, 122, 143, 253, 175, 101, 92, 205, 43, 170, 70, 183, 173, 162, 130, 226, + 41, 122, 158, 130, 183, 223, 162, 212, 194, 38, 133, 252, 57, 245, 187, 168, + 165, 204, 119, 8, 249, 174, 10, 206, 251, 55, 212, 118, 212, 74, 226, 227, + 141, 138, 122, 204, 83, 14, 175, 248, 18, 159, 79, 79, 100, 56, 37, 229, + 209, 221, 238, 197, 164, 42, 159, 203, 67, 31, 8, 195, 72, 251, 142, 229, + 60, 24, 254, 97, 124, 219, 201, 255, 232, 60, 77, 19, 220, 239, 10, 158, + 62, 117, 245, 167, 63, 38, 216, 169, 209, 29, 245, 17, 4, 241, 218, 83, + 72, 48, 214, 228, 85, 103, 116, 248, 133, 200, 75, 81, 220, 207, 59, 226, + 102, 50, 238, 138, 44, 120, 162, 220, 105, 5, 120, 11, 153, 98, 144, 4, + 197, 217, 39, 235, 141, 148, 123, 51, 213, 255, 144, 17, 189, 144, 214, 246, + 45, 95, 229, 127, 107, 19, 164, 143, 48, 210, 29, 249, 66, 11, 171, 191, + 73, 99, 161, 114, 190, 80, 31, 215, 67, 16, 187, 246, 47, 110, 157, 33, + 208, 151, 122, 2, 228, 161, 51, 9, 215, 33, 246, 67, 44, 19, 41, 29, + 10, 42, 130, 244, 95, 45, 199, 156, 251, 151, 210, 121, 198, 52, 44, 87, + 214, 126, 214, 93, 242, 201, 31, 44, 250, 139, 78, 59, 95, 116, 45, 100, + 187, 97, 206, 143, 158, 54, 98, 113, 30, 101, 151, 56, 187, 116, 199, 157, + 108, 136, 90, 36, 85, 253, 171, 140, 253, 14, 229, 238, 65, 220, 56, 162, + 194, 138, 46, 251, 90, 92, 121, 202, 202, 98, 133, 78, 229, 87, 31, 158, + 12, 175, 122, 17, 65, 10, 163, 51, 163, 95, 143, 208, 9, 192, 58, 29, + 130, 4, 237, 194, 246, 82, 11, 20, 49, 26, 177, 34, 202, 180, 210, 111, + 234, 151, 37, 27, 225, 7, 205, 35, 242, 176, 98, 232, 60, 89, 99, 33, + 233, 106, 236, 96, 248, 71, 101, 133, 44, 190, 241, 76, 113, 146, 181, 106, + 191, 130, 100, 127, 206, 138, 118, 124, 159, 138, 215, 82, 22, 224, 17, 114, + 127, 109, 203, 60, 33, 67, 126, 145, 25, 199, 88, 97, 150, 40, 68, 185, + 144, 218, 230, 81, 203, 223, 45, 209, 250, 22, 234, 12, 153, 49, 19, 107, + 97, 79, 126, 100, 128, 16, 12, 83, 74, 94, 23, 159, 192, 193, 74, 153, + 246, 12, 157, 248, 106, 34, 35, 64, 99, 184, 137, 91, 26, 154, 127, 155, + 218, 36, 185, 64, 26, 41, 236, 232, 223, 159, 10, 29, 165, 12, 244, 214, + 231, 231, 212, 154, 169, 66, 39, 153, 129, 38, 40, 46, 140, 140, 172, 0, + 251, 41, 244, 153, 56, 180, 67, 22, 40, 33, 9, 111, 79, 11, 215, 49, + 66, 195, 45, 113, 22, 41, 109, 39, 124, 178, 49, 173, 25, 245, 157, 190, + 63, 116, 79, 213, 200, 171, 85, 121, 185, 198, 99, 92, 235, 127, 157, 18, + 45, 201, 187, 193, 140, 79, 33, 65, 24, 11, 175, 105, 233, 47, 242, 36, + 139, 254, 195, 48, 31, 146, 32, 0, 150, 237, 52, 165, 4, 174, 230, 81, + 72, 146, 101, 241, 206, 146, 151, 105, 106, 255, 165, 127, 196, 69, 250, 155, + 248, 177, 254, 232, 30, 109, 169, 33, 76, 112, 72, 214, 254, 113, 170, 234, + 191, 76, 20, 132, 209, 243, 152, 241, 107, 12, 107, 31, 16, 149, 129, 8, + 160, 7, 54, 31, 219, 58, 93, 76, 50, 143, 210, 73, 131, 59, 34, 38, + 88, 9, 217, 193, 206, 147, 54, 244, 11, 240, 180, 243, 123, 68, 124, 81, + 153, 132, 49, 38, 33, 220, 125, 164, 236, 162, 128, 202, 246, 183, 178, 35, + 242, 109, 76, 7, 215, 92, 149, 32, 117, 34, 174, 122, 34, 101, 5, 67, + 79, 24, 48, 75, 194, 8, 12, 98, 113, 36, 13, 79, 16, 94, 249, 110, + 147, 212, 105, 205, 39, 31, 127, 182, 213, 97, 28, 226, 105, 217, 245, 84, + 138, 119, 58, 136, 137, 79, 193, 116, 226, 72, 101, 0, 142, 171, 59, 40, + 203, 158, 100, 187, 137, 8, 9, 125, 233, 16, 241, 192, 135, 4, 72, 132, + 89, 126, 34, 0, 197, 80, 159, 101, 77, 18, 52, 179, 249, 169, 95, 125, + 120, 18, 56, 177, 106, 6, 100, 99, 197, 197, 111, 104, 120, 211, 163, 86, + 224, 106, 157, 48, 112, 84, 232, 171, 172, 220, 107, 136, 118, 170, 105, 16, + 133, 223, 77, 65, 61, 41, 184, 88, 67, 98, 175, 216, 139, 56, 140, 26, + 18, 179, 212, 180, 218, 235, 78, 180, 154, 144, 195, 188, 126, 205, 37, 58, + 203, 223, 248, 156, 87, 139, 176, 77, 244, 117, 77, 148, 85, 187, 142, 119, + 144, 113, 128, 217, 33, 5, 107, 247, 10, 178, 66, 206, 128, 187, 155, 161, + 150, 166, 9, 194, 18, 87, 82, 5, 42, 74, 250, 215, 83, 145, 8, 158, + 182, 156, 82, 161, 19, 87, 92, 77, 14, 7, 208, 23, 8, 13, 59, 57, + 167, 252, 236, 167, 68, 206, 208, 173, 237, 84, 141, 14, 118, 250, 194, 37, + 131, 146, 23, 17, 37, 228, 42, 134, 130, 193, 34, 83, 151, 107, 227, 133, + 189, 157, 96, 73, 176, 115, 205, 111, 159, 89, 182, 43, 180, 27, 36, 57, + 30, 151, 83, 181, 2, 2, 53, 17, 231, 175, 92, 52, 97, 124, 25, 172, + 17, 206, 83, 37, 79, 60, 174, 47, 181, 207, 115, 216, 0, 59, 178, 186, + 222, 154, 48, 10, 203, 237, 168, 102, 67, 97, 12, 80, 164, 196, 36, 102, + 249, 198, 223, 40, 139, 247, 238, 100, 167, 179, 209, 170, 131, 198, 166, 105, + 139, 118, 164, 153, 86, 75, 187, 187, 197, 160, 68, 198, 18, 67, 72, 85, + 158, 8, 198, 13, 38, 133, 227, 47, 6, 64, 250, 136, 178, 128, 108, 116, + 81, 186, 206, 233, 159, 179, 60, 114, 136, 222, 26, 198, 221, 9, 223, 32, + 123, 35, 23, 188, 146, 155, 213, 76, 159, 32, 252, 211, 185, 1, 157, 178, + 135, 227, 248, 103, 157, 213, 189, 148, 107, 135, 236, 254, 236, 112, 211, 216, + 133, 146, 65, 193, 156, 12, 68, 129, 130, 145, 203, 140, 174, 99, 164, 145, + 36, 252, 41, 175, 206, 147, 115, 196, 4, 174, 108, 17, 122, 230, 134, 147, + 226, 163, 123, 125, 195, 16, 122, 59, 157, 243, 224, 222, 35, 75, 158, 165, + 183, 96, 220, 251, 154, 155, 140, 144, 238, 87, 118, 32, 40, 120, 50, 237, + 231, 139, 167, 105, 32, 225, 232, 86, 220, 154, 75, 196, 71, 65, 93, 220, + 61, 119, 51, 177, 246, 221, 145, 96, 123, 19, 25, 236, 101, 58, 161, 73, + 84, 176, 133, 105, 196, 134, 172, 27, 162, 226, 224, 55, 16, 137, 168, 193, + 190, 36, 174, 21, 216, 214, 118, 104, 129, 255, 68, 151, 108, 167, 109, 82, + 66, 183, 246, 156, 70, 234, 152, 129, 21, 156, 244, 102, 179, 68, 253, 171, + 86, 189, 188, 191, 254, 81, 210, 173, 115, 204, 35, 164, 144, 108, 236, 225, + 100, 49, 60, 210, 38, 90, 187, 49, 180, 192, 94, 27, 241, 255, 99, 158, + 7, 237, 83, 24, 236, 15, 188, 123, 165, 197, 98, 230, 62, 46, 224, 117, + 139, 102, 180, 131, 227, 218, 54, 126, 52, 152, 148, 252, 217, 93, 32, 154, + 96, 161, 242, 40, 170, 26, 56, 74, 254, 10, 15, 19, 201, 213, 81, 46, + 158, 233, 148, 163, 223, 116, 67, 170, 168, 17, 52, 115, 222, 60, 24, 251, + 6, 74, 89, 86, 242, 245, 45, 128, 182, 3, 195, 154, 20, 179, 113, 153, + 44, 242, 180, 83, 26, 92, 220, 87, 99, 40, 234, 36, 47, 104, 5, 216, + 15, 75, 28, 250, 13, 84, 199, 155, 151, 61, 58, 214, 142, 173, 215, 72, + 185, 60, 233, 73, 102, 177, 181, 170, 7, 48, 166, 110, 32, 227, 24, 254, + 43, 157, 97, 119, 1, 125, 154, 244, 80, 196, 119, 70, 137, 163, 29, 157, + 21, 96, 40, 77, 149, 43, 89, 115, 78, 66, 67, 78, 130, 122, 141, 108, + 245, 94, 13, 91, 233, 28, 99, 104, 150, 29, 104, 122, 221, 186, 150, 126, + 164, 59, 147, 132, 74, 1, 84, 129, 134, 199, 184, 19, 164, 172, 218, 226, + 69, 96, 187, 3, 219, 55, 20, 36, 43, 220, 131, 166, 139, 173, 189, 7, + 95, 213, 220, 66, 112, 32, 44, 231, 163, 42, 23, 106, 253, 98, 142, 233, + 108, 164, 242, 111, 223, 130, 113, 101, 180, 103, 69, 79, 3, 212, 134, 113, + 14, 252, 41, 247, 87, 188, 147, 176, 171, 218, 249, 176, 197, 157, 118, 13, + 73, 246, 206, 106, 50, 120, 17, 148, 147, 164, 185, 70, 144, 158, 116, 214, + 92, 246, 184, 68, 85, 100, 240, 154, 2, 156, 164, 212, 110, 241, 153, 129, + 7, 222, 203, 157, 48, 94, 103, 89, 110, 197, 102, 10, 76, 234, 22, 12, + 104, 202, 167, 57, 56, 178, 52, 73, 40, 212, 95, 196, 212, 166, 85, 15, + 41, 81, 141, 124, 130, 100, 79, 100, 175, 126, 225, 151, 102, 116, 43, 17, + 190, 116, 116, 79, 51, 59, 243, 149, 11, 121, 3, 234, 103, 221, 234, 201, + 245, 5, 11, 20, 29, 181, 138, 67, 190, 119, 205, 66, 225, 155, 66, 14, + 205, 68, 114, 207, 7, 180, 117, 185, 176, 204, 9, 9, 126, 205, 58, 142, + 28, 136, 232, 53, 149, 237, 169, 44, 185, 78, 143, 99, 153, 143, 187, 157, + 87, 106, 201, 63, 2, 205, 96, 226, 4, 28, 208, 81, 197, 98, 126, 168, + 170, 63, 29, 15, 228, 23, 82, 12, 109, 204, 227, 231, 228, 87, 196, 63, + 117, 68, 31, 206, 19, 177, 225, 66, 233, 244, 58, 185, 208, 188, 153, 253, + 0, 60, 122, 11, 36, 193, 235, 90, 21, 89, 103, 232, 187, 68, 214, 232, + 180, 13, 143, 157, 99, 180, 232, 213, 90, 113, 194, 193, 194, 230, 242, 45, + 135, 51, 201, 80, 171, 128, 144, 150, 184, 193, 211, 22, 74, 186, 176, 237, + 133, 181, 83, 216, 250, 76, 28, 144, 255, 76, 29, 64, 27, 25, 54, 88, + 161, 132, 38, 34, 236, 32, 77, 106, 157, 6, 74, 120, 64, 211, 237, 173, + 164, 29, 22, 107, 236, 9, 67, 136, 70, 87, 153, 52, 245, 162, 52, 213, + 109, 66, 123, 116, 19, 54, 210, 216, 16, 72, 192, 249, 183, 108, 193, 60, + 242, 120, 186, 160, 200, 137, 184, 180, 97, 15, 95, 167, 169, 87, 146, 151, + 83, 244, 178, 11, 114, 231, 59, 246, 175, 29, 229, 95, 166, 199, 244, 74, + 6, 79, 7, 15, 150, 53, 55, 148, 10, 214, 117, 214, 214, 18, 111, 23, + 77, 192, 122, 193, 255, 196, 114, 120, 89, 233, 200, 20, 133, 140, 132, 162, + 136, 45, 10, 216, 110, 169, 138, 221, 15, 114, 80, 66, 207, 159, 89, 31, + 183, 6, 112, 209, 114, 85, 57, 171, 99, 14, 83, 218, 19, 240, 133, 147, + 208, 50, 112, 209, 213, 114, 113, 128, 67, 115, 171, 57, 184, 202, 111, 119, + 128, 8, 204, 133, 137, 179, 216, 142, 74, 57, 86, 75, 192, 237, 228, 108, + 69, 105, 193, 141, 250, 76, 204, 128, 155, 26, 66, 172, 237, 250, 179, 186, + 199, 211, 152, 65, 6, 152, 201, 105, 251, 78, 186, 157, 66, 69, 101, 190, + 17, 230, 96, 168, 156, 29, 7, 59, 250, 141, 145, 141, 234, 100, 149, 39, + 172, 205, 57, 39, 61, 6, 218, 254, 181, 184, 94, 155, 251, 236, 8, 17, + 252, 132, 153, 56, 164, 230, 249, 203, 60, 78, 227, 136, 118, 97, 69, 247, + 170, 83, 230, 125, 104, 85, 239, 19, 220, 15, 148, 251, 249, 196, 138, 38, + 81, 209, 15, 231, 239, 183, 73, 121, 87, 157, 191, 171, 0, 99, 100, 105, + 105, 223, 226, 113, 198, 179, 200, 75, 136, 55, 190, 194, 166, 94, 142, 224, + 39, 193, 163, 138, 3, 203, 220, 34, 118, 216, 34, 142, 111, 227, 241, 205, + 154, 220, 162, 107, 200, 100, 217, 194, 122, 207, 234, 161, 104, 119, 201, 84, + 46, 37, 159, 130, 76, 136, 147, 250, 29, 209, 151, 145, 92, 189, 105, 79, + 101, 117, 4, 209, 229, 171, 22, 168, 11, 210, 160, 120, 158, 218, 39, 129, + 95, 30, 254, 37, 160, 17, 226, 65, 38, 155, 129, 122, 222, 170, 133, 113, + 134, 168, 135, 212, 57, 200, 248, 226, 62, 62, 200, 159, 127, 42, 51, 90, + 49, 28, 134, 6, 226, 227, 159, 163, 142, 179, 173, 151, 168, 47, 106, 150, + 43, 205, 20, 245, 181, 82, 210, 73, 173, 93, 73, 132, 69, 71, 195, 129, + 214, 106, 151, 117, 135, 138, 224, 126, 167, 48, 83, 34, 36, 200, 13, 29, + 239, 80, 11, 224, 146, 30, 165, 79, 231, 209, 119, 168, 138, 217, 100, 202, + 154, 132, 206, 54, 71, 170, 74, 126, 11, 105, 96, 94, 176, 133, 105, 167, + 60, 81, 127, 80, 238, 86, 126, 54, 147, 16, 117, 54, 230, 12, 76, 196, + 8, 177, 11, 61, 177, 113, 30, 40, 18, 26, 18, 55, 37, 74, 94, 243, + 222, 250, 144, 1, 67, 236, 61, 94, 204, 49, 44, 63, 128, 123, 253, 163, + 36, 31, 168, 42, 144, 198, 132, 53, 212, 183, 1, 234, 164, 254, 55, 113, + 19, 28, 184, 210, 113, 4, 95, 146, 92, 164, 152, 120, 176, 218, 237, 134, + 193, 243, 109, 2, 35, 253, 94, 25, 192, 246, 118, 186, 220, 218, 81, 217, + 36, 126, 215, 24, 86, 127, 114, 69, 176, 237, 20, 52, 239, 1, 82, 149, + 90, 227, 216, 108, 176, 100, 41, 68, 64, 97, 13, 13, 10, 132, 104, 252, + 194, 30, 134, 21, 234, 121, 133, 137, 238, 55, 1, 233, 41, 41, 165, 24, + 135, 243, 206, 15, 65, 184, 175, 222, 34, 216, 2, 143, 84, 207, 136, 195, + 96, 7, 114, 230, 244, 158, 69, 30, 62, 183, 157, 58, 157, 248, 35, 163, + 89, 27, 18, 44, 149, 74, 255, 140, 216, 203, 58, 102, 75, 24, 123, 11, + 79, 224, 186, 187, 55, 178, 22, 170, 74, 65, 248, 185, 88, 174, 100, 179, + 42, 147, 165, 94, 149, 106, 1, 14, 49, 135, 110, 240, 201, 36, 145, 118, + 151, 62, 220, 245, 246, 188, 254, 207, 98, 231, 47, 67, 38, 225, 110, 86, + 50, 168, 160, 3, 188, 233, 152, 13, 199, 93, 171, 72, 152, 181, 223, 144, + 105, 206, 64, 198, 51, 125, 118, 168, 107, 110, 42, 87, 126, 137, 100, 52, + 139, 187, 84, 78, 109, 68, 157, 242, 105, 42, 192, 199, 227, 229, 167, 149, + 115, 222, 117, 64, 146, 168, 86, 69, 160, 37, 91, 184, 75, 172, 107, 178, + 205, 113, 109, 197, 143, 177, 69, 241, 131, 191, 103, 112, 145, 194, 234, 152, + 191, 196, 121, 189, 118, 85, 248, 218, 129, 113, 247, 58, 112, 168, 212, 15, + 226, 249, 121, 7, 193, 119, 219, 153, 152, 134, 87, 50, 53, 1, 122, 228, + 133, 70, 218, 235, 176, 226, 181, 228, 247, 171, 237, 208, 93, 219, 210, 204, + 99, 81, 35, 94, 213, 244, 214, 133, 87, 38, 157, 220, 76, 241, 250, 9, + 174, 94, 200, 220, 42, 33, 84, 33, 20, 6, 86, 165, 70, 17, 23, 147, + 58, 74, 222, 31, 41, 174, 132, 226, 158, 2, 97, 151, 118, 118, 199, 237, + 251, 181, 137, 122, 134, 180, 206, 25, 127, 6, 28, 88, 227, 99, 230, 21, + 51, 19, 201, 179, 147, 131, 49, 170, 49, 104, 15, 138, 137, 169, 120, 94, + 205, 80, 43, 230, 239, 124, 165, 225, 36, 228, 209, 108, 204, 135, 125, 157, + 94, 203, 116, 141, 29, 156, 97, 146, 225, 80, 43, 254, 51, 120, 58, 221, + 11, 176, 165, 179, 174, 53, 216, 195, 110, 24, 177, 125, 101, 171, 86, 108, + 182, 14, 91, 146, 246, 127, 249, 192, 221, 143, 211, 90, 9, 12, 130, 246, + 170, 107, 193, 134, 28, 49, 35, 254, 131, 137, 125, 207, 196, 72, 80, 90, + 30, 174, 143, 172, 226, 50, 12, 236, 58, 235, 205, 251, 234, 171, 14, 201, + 232, 131, 230, 212, 162, 143, 189, 179, 44, 100, 224, 49, 15, 155, 170, 228, + 158, 151, 239, 19, 0, 232, 204, 216, 76, 21, 149, 130, 142, 63, 146, 152, + 124, 136, 129, 14, 182, 212, 29, 8, 244, 12, 36, 28, 134, 52, 216, 106, + 229, 107, 150, 8, 223, 247, 117, 229, 251, 216, 158, 228, 97, 240, 148, 228, + 49, 138, 80, 34, 204, 52, 237, 43, 105, 142, 231, 20, 32, 70, 44, 180, + 212, 121, 229, 177, 50, 152, 238, 72, 51, 116, 111, 18, 27, 211, 40, 211, + 97, 226, 18, 155, 21, 216, 166, 165, 37, 234, 56, 121, 165, 159, 197, 87, + 203, 146, 69, 137, 25, 148, 143, 246, 247, 131, 100, 91, 45, 25, 127, 103, + 35, 219, 32, 31, 237, 93, 92, 167, 194, 64, 255, 188, 64, 139, 118, 135, + 212, 56, 216, 167, 102, 36, 220, 109, 21, 147, 92, 78, 8, 65, 213, 179, + 11, 40, 227, 83, 207, 175, 56, 75, 193, 105, 239, 145, 193, 107, 234, 101, + 50, 97, 123, 246, 137, 30, 180, 149, 18, 62, 162, 163, 16, 192, 79, 61, + 222, 25, 35, 181, 13, 10, 90, 25, 216, 76, 219, 117, 100, 244, 159, 172, + 223, 106, 19, 1, 176, 180, 154, 222, 182, 202, 241, 217, 150, 203, 244, 213, + 94, 178, 158, 130, 166, 105, 167, 118, 194, 153, 142, 60, 134, 216, 142, 216, + 254, 2, 7, 54, 26, 197, 25, 138, 74, 39, 101, 107, 168, 110, 24, 58, + 191, 136, 25, 40, 26, 79, 96, 4, 25, 32, 134, 180, 69, 19, 198, 208, + 254, 197, 133, 72, 242, 66, 107, 23, 157, 143, 117, 50, 224, 198, 246, 8, + 19, 49, 213, 159, 9, 201, 160, 158, 200, 59, 145, 119, 110, 58, 190, 132, + 168, 220, 64, 171, 103, 140, 202, 167, 130, 190, 195, 57, 194, 90, 11, 214, + 19, 53, 68, 88, 89, 14, 235, 20, 50, 249, 248, 100, 241, 10, 149, 35, + 93, 4, 84, 62, 75, 41, 223, 81, 56, 18, 14, 101, 224, 40, 118, 53, + 252, 72, 194, 185, 15, 235, 120, 170, 171, 237, 242, 201, 96, 157, 93, 248, + 227, 156, 239, 249, 190, 10, 177, 147, 77, 18, 157, 53, 114, 233, 168, 14, + 28, 80, 50, 89, 248, 127, 156, 98, 193, 111, 202, 38, 248, 60, 243, 240, + 198, 122, 227, 160, 117, 138, 247, 171, 235, 47, 23, 245, 177, 12, 24, 213, + 214, 117, 210, 86, 85, 55, 153, 25, 16, 53, 195, 81, 247, 217, 104, 109, + 170, 63, 79, 169, 38, 150, 42, 167, 206, 230, 51, 109, 62, 202, 205, 164, + 28, 240, 90, 82, 119, 57, 222, 95, 195, 106, 193, 197, 180, 73, 24, 108, + 143, 114, 54, 29, 100, 255, 124, 30, 143, 120, 147, 84, 110, 157, 53, 226, + 104, 117, 65, 60, 187, 173, 94, 59, 132, 121, 145, 188, 220, 105, 4, 48, + 89, 130, 82, 236, 212, 138, 179, 197, 182, 115, 6, 83, 196, 132, 184, 148, + 183, 101, 141, 92, 84, 153, 147, 133, 212, 8, 250, 226, 167, 209, 22, 95, + 44, 103, 243, 27, 111, 105, 128, 110, 88, 110, 190, 229, 81, 26, 219, 229, + 83, 247, 16, 17, 158, 228, 197, 32, 193, 223, 184, 178, 89, 21, 43, 254, + 124, 144, 200, 131, 138, 5, 107, 98, 139, 16, 184, 127, 244, 51, 141, 88, + 178, 132, 205, 239, 123, 14, 34, 2, 244, 238, 154, 230, 146, 87, 15, 20, + 164, 174, 159, 28, 211, 81, 230, 227, 158, 16, 168, 8, 18, 105, 177, 68, + 50, 127, 64, 73, 123, 233, 44, 34, 159, 133, 66, 100, 163, 184, 244, 171, + 240, 235, 230, 160, 137, 131, 200, 230, 189, 136, 137, 240, 110, 253, 0, 250, + 52, 126, 123, 209, 83, 189, 61, 243, 153, 60, 36, 157, 156, 141, 175, 212, + 219, 217, 33, 144, 133, 126, 7, 41, 228, 77, 247, 47, 162, 47, 3, 157, + 32, 219, 149, 138, 51, 181, 65, 242, 51, 76, 185, 51, 5, 188, 216, 33, + 31, 179, 247, 93, 55, 241, 103, 253, 14, 6, 32, 17, 137, 194, 126, 235, + 132, 115, 93, 167, 187, 190, 147, 190, 255, 120, 166, 38, 118, 241, 129, 163, + 37, 39, 155, 142, 37, 147, 134, 221, 136, 99, 114, 152, 250, 143, 53, 104, + 103, 7, 37, 178, 195, 124, 200, 196, 34, 8, 247, 255, 156, 141, 29, 202, + 239, 70, 189, 144, 0, 167, 182, 105, 57, 205, 218, 54, 151, 29, 7, 76, + 7, 84, 20, 246, 185, 216, 93, 21, 96, 25, 115, 176, 38, 180, 177, 224, + 112, 104, 92, 17, 152, 55, 211, 21, 210, 98, 249, 201, 21, 85, 84, 185, + 53, 59, 147, 198, 1, 251, 185, 235, 132, 73, 67, 194, 220, 120, 191, 206, + 73, 53, 158, 237, 102, 41, 23, 133, 14, 81, 47, 204, 9, 142, 124, 180, + 115, 236, 180, 190, 218, 68, 92, 113, 54, 250, 174, 99, 126, 1, 186, 88, + 231, 96, 51, 147, 236, 164, 135, 210, 75, 242, 196, 53, 104, 101, 233, 0, + 129, 173, 53, 118, 42, 188, 139, 187, 251, 143, 37, 222, 198, 168, 194, 103, + 107, 56, 240, 213, 98, 0, 65, 112, 187, 230, 203, 207, 104, 124, 78, 130, + 66, 156, 214, 95, 22, 46, 181, 254, 15, 201, 138, 160, 138, 171, 202, 3, + 169, 187, 110, 58, 43, 218, 62, 112, 49, 206, 186, 161, 31, 140, 183, 84, + 143, 250, 217, 123, 9, 210, 87, 1, 208, 77, 143, 33, 6, 237, 173, 108, + 187, 137, 131, 148, 145, 22, 123, 142, 146, 156, 223, 61, 124, 151, 57, 17, + 88, 139, 56, 8, 26, 205, 163, 193, 72, 201, 209, 220, 215, 97, 172, 73, + 99, 139, 111, 125, 94, 196, 78, 235, 224, 103, 38, 237, 9, 142, 131, 229, + 45, 247, 172, 219, 29, 102, 67, 124, 171, 113, 2, 85, 148, 56, 150, 227, + 45, 147, 200, 171, 42, 244, 128, 106, 2, 47, 245, 211, 163, 240, 41, 86, + 50, 70, 44, 91, 166, 247, 110, 234, 138, 152, 4, 100, 49, 248, 198, 51, + 124, 253, 126, 122, 30, 165, 0, 183, 248, 65, 30, 156, 161, 52, 164, 76, + 44, 198, 99, 20, 24, 97, 93, 232, 104, 51, 200, 0, 153, 67, 93, 172, + 94, 217, 127, 34, 29, 64, 149, 41, 78, 211, 63, 188, 61, 102, 2, 127, + 166, 194, 5, 59, 203, 5, 224, 68, 250, 58, 202, 236, 218, 235, 168, 0, + 205, 82, 53, 99, 51, 144, 0, 140, 45, 46, 213, 207, 17, 221, 47, 85, + 211, 87, 2, 35, 167, 236, 191, 70, 147, 201, 200, 69, 1, 228, 136, 243, + 122, 253, 34, 201, 92, 90, 194, 8, 119, 197, 197, 178, 157, 207, 170, 147, + 232, 5, 200, 241, 6, 27, 120, 242, 232, 163, 26, 234, 230, 50, 214, 194, + 125, 135, 62, 28, 118, 24, 155, 39, 166, 250, 204, 189, 169, 94, 110, 81, + 222, 81, 127, 71, 49, 176, 178, 37, 63, 219, 72, 0, 100, 255, 201, 70, + 177, 208, 81, 101, 177, 31, 130, 187, 196, 119, 161, 217, 207, 216, 59, 106, + 15, 56, 134, 229, 99, 68, 73, 215, 9, 25, 119, 82, 88, 19, 184, 42, + 38, 40, 176, 6, 34, 167, 249, 143, 6, 216, 128, 139, 75, 3, 229, 126, + 121, 187, 68, 219, 187, 99, 154, 175, 240, 86, 75, 40, 133, 146, 223, 105, + 220, 83, 126, 90, 206, 136, 102, 199, 36, 217, 56, 78, 226, 138, 59, 142, + 223, 68, 175, 191, 83, 224, 208, 195, 2, 102, 168, 194, 158, 231, 143, 162, + 83, 92, 93, 238, 12, 231, 142, 41, 106, 66, 178, 68, 83, 155, 24, 102, + 150, 112, 1, 27, 175, 239, 85, 175, 61, 75, 157, 245, 121, 62, 171, 217, + 55, 218, 86, 45, 10, 228, 203, 193, 216, 90, 142, 109, 232, 168, 17, 149, + 145, 169, 199, 134, 194, 110, 104, 66, 130, 215, 179, 205, 6, 183, 93, 47, + 131, 8, 104, 12, 169, 92, 69, 43, 193, 77, 223, 238, 36, 15, 59, 136, + 95, 87, 196, 169, 35, 118, 252, 19, 6, 247, 172, 219, 159, 109, 118, 154, + 10, 199, 227, 164, 36, 85, 27, 37, 52, 149, 85, 107, 134, 203, 39, 112, + 63, 235, 229, 225, 141, 127, 46, 188, 125, 48, 183, 137, 79, 157, 251, 128, + 214, 29, 60, 192, 43, 20, 22, 77, 62, 5, 229, 201, 61, 217, 181, 68, + 161, 232, 220, 189, 206, 170, 48, 199, 251, 10, 93, 153, 112, 35, 81, 174, + 17, 220, 54, 183, 4, 229, 14, 231, 33, 14, 63, 121, 125, 205, 101, 110, + 255, 145, 55, 130, 56, 4, 236, 171, 27, 10, 130, 188, 115, 125, 104, 178, + 41, 100, 48, 200, 231, 41, 156, 32, 125, 22, 167, 209, 221, 201, 63, 165, + 210, 15, 14, 83, 162, 45, 176, 131, 195, 34, 145, 120, 155, 67, 82, 254, + 231, 179, 149, 97, 4, 84, 30, 62, 140, 39, 235, 91, 145, 92, 89, 87, + 96, 144, 96, 223, 153, 0, 28, 117, 238, 168, 40, 11, 140, 197, 162, 172, + 72, 23, 120, 153, 147, 195, 6, 39, 36, 54, 174, 202, 182, 74, 232, 30, + 240, 10, 130, 188, 127, 2, 48, 68, 9, 191, 245, 176, 249, 169, 19, 21, + 154, 45, 249, 114, 137, 223, 190, 252, 87, 36, 85, 242, 96, 21, 234, 18, + 157, 108, 86, 179, 103, 87, 149, 121, 231, 19, 111, 157, 154, 171, 158, 128, + 68, 253, 157, 146, 9, 11, 82, 101, 218, 181, 37, 73, 31, 19, 122, 211, + 104, 102, 172, 244, 119, 94, 235, 143, 241, 113, 24, 211, 132, 227, 169, 254, + 60, 118, 45, 122, 177, 97, 161, 170, 233, 212, 139, 23, 179, 61, 117, 175, + 126, 18, 119, 242, 14, 67, 254, 147, 62, 61, 58, 54, 42, 75, 134, 163, + 134, 56, 20, 222, 1, 199, 168, 38, 142, 114, 14, 84, 106, 218, 24, 245, + 129, 59, 86, 217, 80, 79, 119, 218, 53, 136, 124, 63, 90, 179, 205, 112, + 192, 116, 186, 223, 65, 52, 109, 169, 196, 209, 73, 239, 124, 224, 15, 78, + 134, 164, 65, 189, 58, 22, 166, 57, 64, 104, 185, 101, 43, 231, 254, 145, + 156, 74, 38, 201, 121, 28, 25, 221, 129, 82, 26, 14, 36, 32, 158, 208, + 70, 2, 201, 70, 190, 208, 246, 54, 239, 158, 140, 212, 225, 209, 177, 86, + 31, 32, 45, 93, 207, 255, 12, 176, 154, 217, 193, 166, 61, 241, 53, 80, + 37, 214, 34, 65, 207, 114, 163, 132, 116, 133, 63, 217, 234, 5, 111, 188, + 79, 1, 110, 88, 156, 17, 242, 1, 138, 105, 144, 213, 123, 212, 7, 164, + 200, 175, 161, 145, 108, 104, 174, 202, 202, 35, 153, 88, 138, 105, 58, 143, + 57, 227, 90, 38, 189, 38, 66, 80, 222, 174, 7, 202, 57, 236, 239, 104, + 51, 26, 252, 140, 2, 74, 4, 163, 211, 199, 202, 185, 65, 203, 13, 210, + 69, 228, 115, 31, 100, 143, 189, 100, 228, 209, 107, 55, 72, 150, 255, 144, + 232, 155, 15, 42, 18, 149, 49, 207, 32, 148, 178, 112, 254, 67, 51, 14, + 217, 41, 203, 217, 205, 101, 223, 161, 148, 33, 92, 164, 250, 91, 80, 251, + 104, 157, 225, 172, 18, 245, 5, 54, 30, 8, 254, 109, 3, 202, 215, 179, + 161, 236, 147, 104, 254, 232, 217, 124, 178, 1, 206, 38, 168, 77, 8, 112, + 234, 154, 162, 94, 3, 90, 94, 114, 137, 115, 42, 98, 202, 0, 214, 202, + 65, 93, 52, 179, 123, 74, 86, 10, 171, 211, 171, 44, 226, 56, 13, 163, + 7, 146, 57, 253, 115, 93, 156, 132, 119, 146, 107, 98, 218, 19, 195, 5, + 195, 190, 231, 218, 143, 48, 65, 102, 92, 0, 244, 108, 148, 144, 214, 99, + 128, 208, 85, 124, 5, 75, 38, 131, 93, 38, 21, 170, 24, 105, 170, 135, + 152, 21, 38, 191, 251, 88, 178, 62, 84, 177, 239, 61, 156, 63, 47, 195, + 117, 159, 198, 182, 126, 216, 103, 165, 158, 51, 70, 34, 33, 241, 216, 11, + 50, 152, 157, 100, 30, 66, 147, 88, 38, 17, 251, 19, 182, 71, 65, 199, + 150, 215, 188, 188, 80, 83, 2, 83, 73, 183, 251, 85, 101, 25, 173, 50, + 243, 138, 194, 98, 209, 104, 219, 25, 45, 111, 172, 115, 238, 149, 4, 205, + 123, 112, 218, 192, 247, 102, 191, 30, 225, 230, 36, 188, 219, 220, 19, 213, + 127, 226, 227, 17, 90, 216, 88, 129, 249, 230, 91, 42, 111, 102, 45, 42, + 175, 161, 188, 195, 184, 238, 57, 69, 88, 168, 167, 23, 64, 47, 201, 51, + 79, 65, 117, 254, 146, 100, 8, 30, 209, 42, 138, 132, 209, 241, 66, 249, + 228, 192, 48, 21, 75, 202, 123, 99, 76, 87, 34, 99, 32, 224, 140, 94, + 90, 178, 47, 165, 23, 227, 92, 218, 45, 44, 104, 9, 23, 94, 254, 195, + 16, 12, 105, 135, 48, 225, 7, 139, 148, 199, 157, 139, 243, 71, 254, 15, + 64, 143, 140, 3, 221, 218, 117, 118, 34, 177, 156, 50, 220, 99, 219, 4, + 247, 244, 16, 100, 51, 73, 85, 181, 24, 127, 102, 173, 238, 205, 143, 68, + 63, 44, 197, 106, 165, 150, 11, 244, 198, 36, 101, 10, 79, 207, 183, 214, + 228, 226, 226, 235, 77, 11, 175, 80, 90, 197, 35, 99, 7, 121, 208, 236, + 141, 171, 176, 158, 219, 162, 166, 168, 147, 2, 131, 180, 57, 229, 106, 63, + 194, 250, 21, 63, 152, 16, 109, 20, 208, 227, 225, 10, 22, 2, 223, 128, + 89, 100, 47, 101, 165, 0, 147, 198, 47, 109, 94, 113, 183, 101, 113, 248, + 79, 21, 26, 141, 176, 52, 118, 71, 143, 174, 194, 248, 199, 194, 245, 105, + 112, 92, 180, 22, 184, 218, 78, 192, 41, 17, 171, 143, 203, 2, 81, 178, + 177, 138, 101, 113, 190, 77, 70, 73, 85, 228, 194, 2, 70, 191, 54, 43, + 188, 233, 27, 135, 140, 127, 10, 59, 38, 86, 226, 127, 166, 132, 69, 21, + 200, 107, 33, 89, 24, 152, 88, 90, 75, 144, 236, 44, 10, 121, 139, 169, + 113, 127, 104, 227, 164, 145, 69, 196, 233, 237, 127, 132, 204, 244, 178, 247, + 191, 207, 63, 135, 214, 135, 213, 151, 44, 43, 190, 32, 241, 221, 118, 81, + 145, 43, 29, 244, 239, 78, 245, 115, 229, 178, 255, 147, 16, 149, 255, 154, + 217, 226, 234, 99, 247, 146, 209, 42, 9, 74, 220, 199, 178, 165, 246, 188, + 22, 51, 136, 38, 63, 125, 45, 108, 190, 111, 72, 248, 57, 16, 107, 120, + 245, 158, 215, 136, 9, 25, 61, 162, 148, 109, 112, 193, 56, 81, 121, 143, + 208, 225, 20, 130, 245, 12, 81, 156, 189, 102, 23, 51, 135, 76, 205, 59, + 197, 152, 35, 80, 127, 168, 223, 48, 20, 104, 57, 69, 132, 53, 72, 220, + 161, 178, 219, 33, 37, 245, 58, 199, 17, 246, 39, 2, 84, 251, 20, 62, + 21, 56, 209, 143, 149, 24, 68, 59, 17, 240, 215, 95, 195, 188, 231, 97, + 41, 32, 98, 57, 107, 172, 90, 159, 132, 150, 226, 75, 151, 144, 12, 111, + 6, 253, 112, 213, 28, 179, 232, 233, 73, 139, 84, 232, 204, 0, 148, 77, + 48, 183, 37, 213, 67, 195, 211, 206, 12, 110, 212, 180, 201, 229, 77, 7, + 48, 221, 44, 102, 23, 168, 145, 200, 77, 103, 7, 173, 247, 84, 110, 123, + 23, 5, 145, 154, 124, 95, 103, 89, 78, 136, 74, 47, 136, 86, 135, 250, + 60, 228, 64, 78, 228, 172, 111, 204, 89, 144, 119, 8, 248, 81, 70, 113, + 89, 113, 50, 70, 124, 182, 58, 179, 77, 197, 160, 136, 41, 195, 19, 163, + 222, 23, 34, 70, 203, 156, 137, 209, 146, 213, 112, 210, 203, 138, 236, 36, + 24, 57, 106, 75, 115, 112, 43, 229, 239, 154, 133, 160, 211, 36, 241, 229, + 94, 110, 224, 182, 162, 85, 189, 20, 125, 9, 26, 137, 185, 177, 14, 138, + 5, 225, 132, 174, 244, 209, 187, 92, 140, 29, 158, 111, 150, 8, 32, 99, + 99, 142, 213, 19, 101, 164, 64, 190, 61, 219, 198, 118, 246, 217, 110, 173, + 248, 24, 100, 216, 190, 118, 198, 209, 64, 238, 205, 176, 46, 116, 131, 103, + 243, 148, 123, 69, 136, 144, 46, 112, 112, 162, 219, 21, 205, 136, 193, 152, + 96, 134, 16, 22, 146, 190, 194, 19, 119, 47, 44, 67, 131, 166, 109, 215, + 159, 90, 88, 212, 11, 71, 235, 55, 31, 4, 113, 172, 187, 169, 10, 144, + 169, 108, 79, 145, 7, 29, 24, 221, 230, 28, 113, 32, 190, 160, 67, 40, + 43, 107, 222, 221, 175, 180, 200, 217, 15, 128, 253, 206, 203, 106, 167, 163, + 89, 29, 28, 247, 240, 14, 121, 133, 218, 154, 167, 77, 98, 149, 151, 145, + 4, 78, 232, 135, 195, 121, 157, 216, 178, 211, 243, 201, 71, 220, 150, 119, + 74, 71, 110, 200, 234, 100, 105, 248, 47, 25, 35, 1, 241, 166, 6, 88, + 41, 246, 176, 181, 21, 75, 150, 20, 227, 19, 64, 226, 209, 194, 121, 174, + 240, 219, 133, 253, 161, 146, 230, 69, 122, 42, 165, 82, 78, 45, 185, 61, + 12, 14, 148, 13, 119, 155, 157, 28, 90, 226, 119, 9, 201, 199, 64, 93, + 120, 115, 138, 156, 235, 123, 52, 111, 149, 48, 73, 181, 204, 181, 10, 157, + 16, 55, 100, 243, 10, 29, 159, 139, 88, 16, 1, 31, 201, 242, 2, 237, + 186, 181, 217, 139, 102, 205, 119, 197, 201, 221, 108, 205, 171, 54, 109, 31, + 76, 199, 28, 160, 214, 14, 201, 25, 211, 189, 144, 44, 69, 70, 205, 79, + 150, 149, 108, 23, 8, 171, 60, 18, 127, 161, 41, 71, 239, 168, 89, 140, + 49, 149, 157, 109, 232, 141, 227, 239, 247, 114, 174, 129, 19, 252, 130, 74, + 202, 224, 73, 122, 246, 47, 147, 8, 37, 60, 253, 101, 11, 171, 160, 39, + 92, 180, 183, 40, 254, 233, 117, 200, 139, 37, 140, 28, 35, 8, 10, 40, + 167, 247, 248, 84, 215, 58, 170, 2, 7, 1, 69, 214, 10, 7, 233, 209, + 181, 212, 34, 68, 46, 141, 198, 137, 248, 45, 130, 97, 123, 104, 141, 17, + 126, 7, 199, 55, 194, 160, 69, 39, 13, 70, 41, 63, 205, 99, 1, 69, + 46, 92, 77, 56, 20, 247, 224, 226, 60, 153, 81, 180, 91, 159, 156, 27, + 119, 114, 126, 210, 26, 123, 165, 204, 237, 81, 75, 130, 45, 60, 0, 155, + 11, 125, 27, 202, 35, 230, 101, 164, 86, 117, 226, 23, 171, 253, 222, 223, + 38, 104, 224, 124, 92, 251, 110, 145, 247, 198, 158, 25, 172, 84, 49, 87, + 1, 168, 95, 124, 146, 5, 46, 179, 198, 235, 69, 200, 63, 212, 59, 110, + 52, 195, 54, 71, 169, 234, 189, 58, 180, 149, 194, 10, 118, 99, 66, 66, + 123, 192, 248, 51, 237, 129, 10, 143, 94, 55, 135, 247, 56, 163, 40, 139, + 150, 192, 142, 64, 169, 90, 42, 116, 228, 62, 67, 130, 212, 212, 23, 210, + 182, 95, 109, 224, 185, 255, 156, 102, 184, 171, 42, 98, 217, 218, 27, 80, + 171, 125, 49, 233, 16, 238, 42, 102, 61, 95, 180, 49, 192, 67, 112, 143, + 106, 145, 185, 239, 180, 181, 120, 24, 127, 215, 233, 123, 235, 104, 228, 248, + 223, 90, 211, 211, 76, 179, 198, 253, 220, 171, 247, 171, 11, 237, 17, 249, + 81, 122, 111, 255, 213, 120, 167, 192, 149, 102, 7, 204, 86, 107, 156, 83, + 174, 18, 237, 143, 85, 76, 245, 189, 86, 90, 118, 69, 100, 140, 121, 17, + 255, 17, 209, 144, 90, 3, 191, 201, 134, 108, 0, 196, 133, 153, 39, 248, + 138, 215, 73, 18, 21, 140, 172, 178, 154, 194, 170, 45, 112, 113, 213, 36, + 155, 0, 30, 213, 186, 39, 6, 241, 92, 111, 139, 52, 84, 58, 218, 187, + 60, 123, 113, 190, 185, 89, 242, 248, 221, 238, 173, 145, 214, 237, 133, 101, + 6, 143, 188, 116, 13, 189, 205, 203, 147, 140, 215, 175, 38, 99, 77, 54, + 98, 146, 54, 101, 40, 206, 175, 26, 195, 33, 63, 20, 210, 96, 227, 125, + 108, 230, 179, 123, 81, 135, 183, 132, 216, 56, 223, 197, 141, 158, 114, 228, + 67, 172, 95, 76, 69, 212, 188, 244, 12, 16, 158, 119, 106, 44, 39, 36, + 38, 164, 173, 182, 172, 210, 176, 19, 125, 6, 36, 138, 77, 65, 219, 30, + 45, 167, 21, 125, 49, 69, 173, 23, 242, 246, 25, 155, 194, 161, 140, 125, + 97, 153, 68, 120, 114, 23, 243, 242, 192, 129, 68, 88, 43, 161, 33, 152, + 130, 232, 179, 70, 156, 219, 198, 1, 135, 3, 178, 49, 92, 30, 125, 185, + 39, 185, 69, 143, 30, 180, 113, 109, 233, 156, 101, 82, 239, 142, 58, 234, + 151, 67, 2, 140, 198, 7, 180, 167, 33, 168, 131, 213, 157, 139, 43, 208, + 27, 217, 245, 115, 0, 59, 155, 69, 236, 209, 101, 139, 211, 247, 2, 41, + 113, 222, 7, 2, 109, 61, 232, 215, 145, 18, 202, 158, 187, 136, 54, 190, + 169, 13, 59, 204, 117, 37, 160, 6, 121, 200, 9, 189, 31, 0, 251, 78, + 223, 43, 122, 5, 42, 24, 74, 247, 241, 68, 42, 49, 28, 153, 3, 40, + 166, 47, 55, 83, 186, 236, 69, 132, 91, 115, 132, 26, 214, 160, 51, 161, + 232, 147, 172, 175, 144, 53, 58, 241, 1, 245, 53, 126, 211, 121, 98, 228, + 65, 166, 9, 186, 93, 111, 249, 87, 109, 85, 218, 177, 160, 225, 99, 131, + 167, 173, 36, 10, 121, 121, 98, 249, 99, 68, 128, 159, 217, 207, 65, 52, + 247, 53, 58, 135, 11, 76, 238, 101, 162, 166, 100, 126, 136, 157, 43, 172, + 186, 157, 138, 2, 132, 141, 165, 152, 92, 234, 3, 92, 81, 111, 83, 239, + 234, 204, 152, 240, 74, 198, 42, 56, 131, 104, 96, 83, 207, 109, 30, 185, + 45, 242, 2, 155, 47, 18, 111, 119, 57, 239, 7, 88, 45, 86, 239, 10, + 178, 146, 58, 248, 96, 166, 234, 253, 202, 224, 111, 120, 216, 70, 205, 29, + 154, 232, 216, 165, 222, 76, 153, 46, 5, 143, 71, 197, 175, 198, 127, 231, + 119, 110, 47, 128, 61, 134, 41, 115, 101, 3, 35, 127, 201, 12, 152, 1, + 163, 41, 91, 233, 10, 230, 150, 44, 140, 234, 164, 184, 214, 218, 114, 23, + 221, 163, 57, 2, 5, 147, 66, 223, 90, 238, 136, 95, 138, 116, 27, 91, + 223, 52, 243, 246, 183, 215, 166, 170, 169, 8, 140, 91, 173, 160, 160, 105, + 69, 241, 31, 33, 33, 148, 215, 67, 130, 181, 1, 114, 104, 206, 192, 195, + 247, 229, 99, 84, 29, 2, 132, 146, 191, 243, 37, 36, 46, 176, 164, 68, + 84, 121, 159, 6, 160, 195, 170, 43, 128, 130, 165, 44, 157, 83, 173, 182, + 93, 90, 202, 227, 133, 140, 39, 203, 202, 2, 49, 96, 178, 190, 147, 15, + 99, 71, 216, 166, 97, 130, 87, 4, 149, 23, 107, 246, 216, 213, 222, 64, + 41, 215, 37, 211, 21, 53, 90, 130, 165, 181, 188, 87, 70, 8, 53, 114, + 227, 18, 192, 19, 200, 195, 83, 228, 1, 171, 202, 229, 92, 92, 227, 48, + 251, 31, 198, 59, 162, 119, 9, 75, 115, 30, 127, 8, 89, 99, 249, 86, + 152, 198, 53, 207, 82, 251, 68, 82, 247, 21, 214, 18, 246, 118, 81, 94, + 240, 34, 174, 233, 205, 204, 71, 0, 254, 24, 178, 166, 248, 12, 70, 187, + 163, 168, 95, 23, 108, 156, 210, 244, 198, 216, 54, 32, 83, 158, 121, 26, + 116, 252, 122, 73, 188, 134, 154, 180, 229, 139, 102, 2, 8, 171, 201, 5, + 187, 57, 35, 254, 35, 19, 161, 16, 88, 215, 158, 148, 249, 201, 65, 177, + 144, 69, 138, 161, 220, 255, 190, 223, 43, 181, 11, 158, 103, 193, 14, 21, + 49, 16, 40, 223, 155, 12, 164, 23, 31, 15, 20, 238, 131, 85, 181, 80, + 149, 128, 196, 123, 155, 236, 9, 94, 252, 182, 54, 62, 215, 115, 115, 224, + 242, 141, 137, 238, 115, 101, 107, 65, 202, 79, 79, 27, 239, 29, 154, 19, + 18, 4, 185, 144, 191, 107, 92, 29, 38, 248, 142, 81, 109, 64, 161, 23, + 73, 93, 31, 114, 51, 81, 98, 209, 69, 27, 43, 22, 4, 168, 88, 60, + 149, 89, 100, 82, 122, 95, 21, 38, 97, 185, 87, 66, 82, 16, 242, 109, + 100, 94, 164, 6, 73, 130, 76, 137, 218, 226, 166, 35, 21, 156, 72, 253, + 148, 228, 142, 134, 41, 145, 15, 144, 215, 187, 120, 239, 195, 203, 44, 250, + 46, 72, 181, 43, 255, 81, 247, 100, 195, 248, 208, 115, 141, 32, 190, 131, + 77, 230, 220, 54, 197, 60, 22, 115, 177, 116, 250, 0, 60, 144, 128, 68, + 245, 231, 199, 216, 17, 216, 227, 120, 221, 68, 233, 236, 202, 121, 189, 237, + 149, 60, 244, 130, 250, 169, 70, 101, 147, 8, 49, 248, 61, 207, 202, 148, + 228, 87, 234, 117, 238, 52, 92, 118, 148, 203, 206, 175, 75, 64, 215, 57, + 70, 196, 52, 62, 29, 116, 241, 185, 96, 131, 201, 219, 16, 3, 188, 159, + 129, 134, 11, 138, 13, 3, 72, 193, 183, 236, 91, 171, 161, 52, 166, 23, + 254, 118, 238, 180, 55, 215, 165, 163, 154, 202, 27, 61, 150, 31, 12, 1, + 249, 0, 12, 29, 132, 213, 168, 105, 53, 112, 54, 2, 236, 131, 230, 3, + 211, 69, 243, 233, 173, 145, 105, 27, 18, 252, 224, 5, 46, 18, 233, 96, + 237, 143, 52, 67, 158, 30, 242, 151, 98, 148, 208, 60, 143, 14, 245, 250, + 185, 151, 111, 147, 145, 197, 165, 233, 18, 178, 240, 83, 228, 213, 237, 58, + 20, 152, 249, 241, 250, 204, 15, 167, 97, 242, 6, 228, 117, 133, 2, 199, + 220, 212, 239, 206, 104, 231, 145, 33, 17, 150, 223, 126, 173, 223, 148, 21, + 228, 41, 63, 37, 19, 102, 73, 95, 196, 40, 151, 2, 19, 239, 182, 22, + 178, 165, 242, 159, 208, 226, 72, 179, 201, 109, 157, 18, 230, 130, 221, 89, + 173, 242, 170, 11, 146, 20, 135, 112, 2, 202, 30, 25, 106, 151, 52, 223, + 1, 3, 18, 151, 74, 113, 49, 186, 112, 160, 121, 38, 233, 155, 188, 237, + 251, 178, 8, 200, 120, 134, 152, 22, 232, 250, 219, 237, 157, 23, 134, 158, + 122, 202, 120, 89, 248, 68, 46, 184, 180, 93, 84, 85, 177, 236, 62, 50, + 103, 62, 81, 105, 33, 15, 97, 203, 192, 132, 219, 70, 203, 104, 162, 98, + 179, 224, 44, 101, 221, 84, 176, 97, 77, 84, 45, 255, 227, 80, 107, 45, + 70, 106, 68, 206, 134, 182, 205, 255, 235, 44, 131, 81, 126, 142, 30, 130, + 87, 133, 227, 15, 200, 194, 5, 230, 230, 169, 65, 116, 104, 193, 196, 214, + 18, 199, 56, 114, 5, 7, 189, 158, 32, 119, 53, 93, 169, 172, 141, 223, + 71, 194, 204, 221, 237, 118, 16, 198, 169, 10, 38, 156, 152, 76, 185, 73, + 15, 227, 118, 57, 149, 160, 14, 158, 18, 139, 117, 249, 142, 12, 175, 252, + 9, 202, 65, 196, 23, 211, 174, 169, 85, 244, 154, 239, 28, 199, 196, 171, + 241, 27, 140, 222, 54, 25, 229, 69, 102, 134, 125, 235, 246, 156, 41, 75, + 212, 225, 169, 207, 88, 246, 136, 176, 27, 40, 205, 228, 239, 24, 217, 42, + 212, 63, 187, 75, 60, 197, 97, 245, 3, 35, 243, 128, 36, 129, 145, 31, + 27, 193, 20, 122, 116, 143, 130, 159, 80, 203, 253, 233, 66, 118, 92, 177, + 83, 55, 141, 189, 115, 240, 125, 107, 8, 221, 237, 171, 24, 183, 220, 174, + 149, 51, 81, 221, 187, 233, 21, 116, 37, 88, 123, 20, 208, 201, 141, 155, + 136, 148, 64, 14, 102, 204, 248, 173, 249, 61, 75, 253, 199, 46, 192, 138, + 79, 83, 161, 127, 235, 140, 173, 158, 127, 232, 77, 17, 45, 207, 154, 51, + 79, 57, 184, 22, 220, 225, 61, 233, 188, 119, 221, 254, 87, 105, 151, 29, + 156, 162, 18, 202, 244, 36, 105, 24, 240, 195, 198, 39, 31, 155, 135, 62, + 220, 180, 53, 70, 121, 254, 234, 194, 79, 177, 181, 75, 23, 20, 217, 209, + 107, 100, 175, 83, 25, 212, 62, 11, 108, 33, 144, 17, 150, 176, 225, 86, + 54, 190, 8, 82, 150, 219, 80, 72, 75, 100, 197, 72, 95, 174, 189, 158, + 109, 146, 103, 67, 101, 165, 191, 178, 148, 32, 173, 147, 195, 145, 27, 119, + 126, 46, 186, 120, 226, 41, 209, 51, 171, 29, 4, 244, 184, 209, 92, 159, + 221, 122, 163, 30, 246, 68, 8, 190, 146, 143, 159, 116, 211, 83, 247, 90, + 241, 193, 10, 58, 250, 60, 69, 182, 204, 181, 207, 107, 37, 104, 150, 14, + 69, 55, 20, 7, 158, 96, 202, 248, 68, 220, 209, 132, 133, 164, 58, 175, + 103, 166, 1, 174, 0, 32, 182, 13, 199, 83, 48, 148, 52, 198, 19, 135, + 58, 46, 109, 164, 49, 199, 26, 109, 132, 19, 46, 118, 59, 27, 202, 73, + 4, 1, 22, 183, 163, 247, 45, 96, 206, 43, 239, 186, 131, 5, 61, 198, + 46, 99, 31, 89, 194, 241, 207, 170, 80, 250, 72, 225, 89, 154, 151, 165, + 171, 42, 59, 58, 68, 73, 178, 88, 153, 111, 247, 233, 19, 130, 51, 194, + 18, 142, 129, 52, 252, 167, 183, 238, 99, 198, 85, 134, 20, 114, 94, 90, + 7, 223, 147, 178, 135, 156, 216, 69, 14, 42, 181, 232, 203, 63, 239, 213, + 42, 225, 189, 223, 15, 238, 219, 62, 218, 15, 210, 141, 184, 226, 11, 228, + 9, 40, 37, 118, 26, 194, 213, 220, 99, 247, 7, 137, 187, 61, 64, 56, + 86, 169, 143, 224, 135, 166, 4, 28, 55, 87, 216, 45, 56, 39, 37, 181, + 234, 38, 4, 241, 184, 43, 134, 108, 245, 247, 230, 99, 162, 95, 214, 92, + 191, 83, 38, 152, 241, 38, 33, 32, 38, 92, 222, 228, 138, 11, 143, 135, + 83, 181, 140, 99, 9, 252, 123, 215, 212, 81, 108, 71, 2, 159, 246, 82, + 118, 186, 48, 69, 212, 147, 218, 61, 183, 170, 130, 233, 227, 145, 101, 156, + 20, 106, 128, 214, 238, 12, 163, 59, 152, 250, 112, 173, 42, 5, 1, 68, + 35, 52, 13, 198, 121, 11, 117, 16, 126, 143, 54, 184, 205, 44, 238, 47, + 218, 75, 112, 228, 183, 55, 22, 189, 35, 146, 27, 44, 229, 190, 241, 110, + 42, 152, 12, 141, 131, 183, 84, 31, 40, 185, 108, 176, 173, 247, 217, 214, + 155, 108, 176, 152, 201, 201, 185, 7, 227, 187, 87, 71, 45, 98, 224, 159, + 125, 230, 132, 19, 233, 98, 174, 93, 80, 245, 32, 94, 253, 35, 150, 68, + 176, 83, 50, 127, 196, 149, 176, 191, 136, 194, 84, 228, 106, 238, 47, 206, + 110, 204, 9, 116, 136, 230, 249, 90, 215, 160, 51, 151, 61, 92, 187, 82, + 129, 101, 75, 238, 22, 166, 132, 86, 183, 113, 149, 215, 39, 242, 214, 148, + 71, 168, 236, 20, 105, 249, 219, 23, 101, 63, 92, 173, 40, 126, 253, 145, + 161, 9, 72, 60, 215, 59, 155, 228, 255, 201, 193, 60, 129, 51, 29, 207, + 237, 43, 145, 161, 41, 115, 98, 19, 138, 253, 66, 232, 233, 186, 79, 114, + 1, 164, 184, 14, 61, 151, 198, 60, 247, 115, 5, 176, 132, 201, 245, 60, + 21, 238, 60, 133, 186, 18, 154, 89, 170, 23, 102, 2, 111, 147, 25, 208, + 152, 173, 13, 58, 125, 181, 115, 218, 196, 107, 173, 192, 60, 94, 140, 254, + 83, 80, 214, 220, 245, 254, 250, 39, 202, 132, 142, 84, 16, 199, 20, 129, + 159, 24, 18, 123, 143, 157, 176, 199, 173, 56, 169, 222, 252, 63, 27, 242, + 137, 138, 253, 143, 4, 209, 124, 86, 243, 170, 152, 121, 231, 24, 238, 35, + 113, 27, 205, 59, 153, 161, 234, 65, 153, 237, 97, 197, 98, 216, 129, 30, + 174, 211, 193, 167, 102, 229, 240, 198, 85, 193, 253, 73, 118, 185, 63, 3, + 227, 165, 139, 38, 109, 214, 108, 253, 48, 227, 253, 219, 1, 226, 89, 47, + 145, 86, 8, 234, 146, 159, 230, 108, 212, 111, 112, 129, 121, 28, 164, 105, + 138, 143, 106, 132, 254, 202, 177, 171, 123, 38, 162, 112, 97, 88, 221, 95, + 5, 161, 222, 76, 234, 253, 239, 231, 13, 62, 243, 80, 164, 204, 67, 229, + 43, 103, 152, 30, 131, 240, 218, 184, 149, 161, 234, 124, 238, 126, 33, 234, + 133, 1, 201, 113, 176, 190, 231, 215, 99, 64, 219, 224, 29, 217, 23, 232, + 185, 215, 56, 14, 128, 31, 227, 227, 80, 213, 239, 224, 36, 144, 26, 243, + 36, 181, 129, 69, 104, 55, 42, 212, 27, 252, 74, 173, 196, 255, 96, 153, + 53, 3, 99, 13, 167, 244, 183, 92, 231, 140, 210, 116, 98, 36, 187, 126, + 84, 77, 144, 109, 126, 138, 53, 237, 100, 96, 209, 68, 204, 61, 104, 246, + 64, 35, 98, 99, 82, 152, 68, 118, 51, 82, 101, 136, 76, 149, 234, 135, + 110, 37, 167, 154, 17, 145, 150, 148, 89, 184, 123, 108, 255, 2, 49, 98, + 101, 125, 88, 110, 2, 146, 130, 120, 212, 249, 21, 164, 164, 161, 47, 201, + 70, 114, 46, 149, 0, 88, 142, 60, 228, 58, 181, 175, 207, 222, 199, 81, + 135, 121, 200, 205, 143, 132, 31, 93, 179, 202, 132, 84, 3, 19, 40, 190, + 99, 120, 38, 42, 165, 159, 18, 153, 99, 212, 120, 4, 237, 237, 8, 57, + 69, 228, 186, 220, 183, 121, 139, 113, 179, 200, 21, 166, 75, 19, 149, 135, + 138, 170, 149, 14, 166, 110, 94, 129, 233, 66, 187, 163, 213, 96, 172, 4, + 145, 205, 41, 25, 97, 26, 66, 99, 104, 172, 227, 73, 193, 35, 142, 228, + 202, 85, 209, 10, 77, 47, 21, 8, 14, 215, 104, 211, 62, 186, 19, 226, + 180, 187, 81, 140, 101, 188, 252, 173, 1, 242, 9, 66, 177, 73, 5, 79, + 230, 53, 67, 28, 207, 98, 199, 52, 27, 66, 153, 200, 135, 247, 246, 210, + 128, 156, 173, 249, 92, 165, 93, 112, 247, 110, 0, 133, 56, 64, 199, 71, + 135, 104, 242, 50, 218, 28, 242, 216, 223, 229, 92, 19, 39, 36, 161, 233, + 104, 205, 56, 92, 20, 44, 81, 244, 215, 85, 116, 79, 44, 104, 236, 197, + 72, 17, 157, 105, 213, 76, 90, 85, 9, 54, 76, 248, 27, 39, 175, 107, + 79, 142, 31, 140, 48, 194, 73, 214, 79, 131, 65, 191, 175, 211, 154, 225, + 182, 226, 90, 169, 178, 95, 71, 89, 3, 4, 83, 27, 152, 218, 67, 67, + 225, 90, 159, 244, 215, 227, 41, 53, 214, 40, 178, 86, 46, 92, 27, 200, + 104, 126, 203, 185, 150, 90, 220, 210, 140, 33, 238, 113, 54, 31, 121, 4, + 49, 132, 62, 250, 9, 180, 120, 241, 248, 86, 67, 254, 57, 166, 141, 34, + 165, 218, 73, 167, 166, 85, 50, 191, 136, 177, 212, 175, 133, 8, 30, 106, + 201, 100, 208, 40, 119, 107, 182, 231, 27, 237, 58, 22, 225, 63, 21, 160, + 176, 7, 223, 124, 229, 53, 246, 170, 155, 70, 75, 68, 204, 221, 146, 48, + 109, 153, 25, 0, 157, 54, 208, 220, 240, 216, 113, 30, 230, 30, 46, 139, + 116, 215, 222, 10, 247, 103, 24, 86, 125, 8, 77, 202, 39, 152, 10, 225, + 131, 18, 117, 227, 249, 127, 160, 143, 86, 128, 207, 99, 207, 224, 42, 110, + 232, 36, 86, 179, 249, 138, 84, 121, 50, 5, 149, 93, 7, 200, 115, 209, + 110, 152, 124, 77, 52, 79, 221, 157, 195, 140, 54, 19, 60, 205, 158, 199, + 127, 207, 7, 117, 11, 227, 197, 72, 199, 187, 184, 43, 95, 0, 61, 143, + 176, 207, 65, 130, 87, 82, 140, 181, 182, 184, 223, 238, 244, 209, 170, 7, + 11, 100, 83, 5, 98, 125, 26, 188, 40, 137, 242, 22, 249, 227, 184, 80, + 44, 145, 32, 143, 254, 218, 115, 107, 76, 139, 212, 87, 253, 12, 11, 121, + 216, 159, 121, 87, 182, 101, 205, 151, 5, 0, 126, 150, 6, 166, 115, 36, + 14, 128, 159, 126, 200, 42, 189, 146, 192, 223, 186, 35, 71, 224, 63, 33, + 211, 207, 93, 66, 201, 31, 66, 220, 66, 97, 107, 95, 157, 213, 92, 81, + 217, 125, 242, 101, 243, 184, 255, 155, 2, 165, 9, 143, 103, 243, 133, 173, + 202, 202, 40, 221, 73, 177, 248, 57, 243, 125, 130, 127, 102, 47, 3, 227, + 27, 203, 33, 179, 249, 117, 28, 112, 157, 0, 210, 139, 43, 15, 192, 47, + 202, 45, 132, 10, 26, 163, 47, 220, 65, 169, 225, 235, 120, 57, 25, 176, + 206, 16, 38, 110, 84, 145, 28, 43, 63, 35, 144, 234, 249, 59, 22, 152, + 16, 175, 248, 2, 6, 109, 55, 92, 124, 77, 237, 166, 207, 82, 238, 140, + 22, 30, 214, 144, 177, 182, 229, 27, 180, 150, 186, 187, 231, 184, 242, 23, + 178, 119, 36, 24, 165, 82, 15, 195, 55, 147, 107, 45, 198, 133, 194, 95, + 20, 146, 8, 222, 235, 67, 80, 119, 234, 48, 223, 163, 51, 60, 217, 228, + 171, 195, 231, 250, 46, 111, 138, 143, 1, 48, 174, 116, 197, 186, 40, 61, + 177, 53, 65, 225, 171, 95, 186, 209, 199, 254, 152, 98, 179, 71, 140, 127, + 193, 177, 171, 61, 227, 117, 130, 92, 148, 43, 199, 156, 176, 219, 52, 218, + 133, 160, 123, 11, 221, 104, 254, 253, 144, 156, 245, 5, 156, 246, 226, 198, + 222, 172, 246, 13, 35, 210, 51, 99, 203, 213, 159, 248, 139, 71, 77, 120, + 75, 195, 89, 11, 122, 125, 43, 57, 30, 233, 45, 10, 87, 102, 171, 47, + 21, 167, 175, 143, 207, 121, 98, 48, 220, 247, 72, 184, 97, 83, 152, 72, + 51, 136, 17, 52, 249, 169, 8, 140, 219, 152, 5, 221, 132, 225, 17, 117, + 28, 72, 220, 69, 199, 108, 140, 175, 206, 165, 41, 39, 77, 194, 249, 154, + 121, 23, 85, 205, 128, 34, 118, 49, 220, 85, 5, 240, 181, 26, 210, 29, + 177, 24, 132, 91, 57, 218, 74, 217, 135, 225, 148, 82, 95, 98, 54, 127, + 58, 1, 85, 12, 122, 2, 58, 81, 16, 32, 168, 153, 186, 97, 214, 81, + 176, 244, 134, 168, 111, 127, 21, 251, 227, 215, 141, 191, 141, 90, 21, 177, + 142, 172, 29, 212, 128, 163, 54, 172, 20, 35, 174, 1, 225, 232, 74, 73, + 226, 154, 236, 45, 211, 64, 28, 142, 90, 175, 147, 230, 243, 66, 160, 207, + 186, 212, 201, 34, 58, 202, 236, 9, 218, 10, 226, 189, 74, 106, 75, 43, + 93, 1, 5, 162, 36, 42, 54, 86, 83, 35, 242, 114, 165, 93, 76, 8, + 94, 21, 110, 101, 241, 119, 219, 78, 115, 182, 5, 105, 116, 73, 50, 193, + 102, 254, 43, 197, 64, 236, 6, 105, 84, 206, 79, 127, 195, 151, 106, 76, + 122, 173, 234, 203, 34, 20, 204, 34, 195, 244, 209, 60, 32, 112, 157, 150, + 185, 49, 35, 11, 41, 230, 21, 63, 137, 1, 127, 147, 193, 77, 136, 174, + 109, 122, 243, 119, 160, 26, 5, 187, 191, 90, 83, 26, 214, 237, 162, 198, + 184, 179, 204, 246, 113, 43, 145, 228, 4, 250, 28, 187, 22, 149, 121, 67, + 94, 202, 229, 64, 35, 204, 174, 106, 180, 40, 224, 146, 117, 146, 217, 9, + 29, 22, 202, 177, 96, 25, 165, 0, 97, 146, 120, 15, 29, 230, 203, 30, + 181, 73, 37, 59, 38, 156, 8, 123, 215, 252, 229, 157, 240, 58, 91, 78, + 3, 189, 39, 232, 28, 175, 195, 69, 94, 127, 176, 218, 32, 40, 236, 113, + 175, 110, 241, 181, 238, 15, 46, 106, 58, 170, 48, 58, 254, 253, 190, 204, + 172, 214, 31, 202, 150, 134, 97, 230, 224, 255, 121, 206, 110, 102, 224, 49, + 94, 248, 23, 109, 243, 23, 208, 50, 120, 155, 166, 16, 193, 8, 111, 212, + 88, 114, 163, 247, 255, 144, 18, 87, 92, 47, 60, 250, 35, 102, 101, 150, + 228, 34, 28, 18, 59, 175, 136, 120, 186, 193, 15, 151, 143, 76, 54, 96, + 157, 183, 62, 4, 245, 231, 132, 94, 131, 139, 192, 253, 72, 194, 242, 7, + 202, 19, 20, 245, 122, 114, 177, 101, 133, 107, 109, 109, 112, 151, 71, 239, + 115, 43, 157, 185, 57, 149, 27, 82, 191, 118, 114, 80, 96, 115, 166, 79, + 166, 59, 23, 91, 223, 159, 217, 68, 63, 155, 173, 200, 73, 32, 199, 233, + 241, 206, 133, 125, 89, 87, 71, 172, 91, 56, 219, 233, 115, 26, 63, 53, + 98, 209, 57, 151, 243, 141, 54, 139, 107, 120, 252, 89, 249, 133, 67, 85, + 144, 135, 86, 238, 9, 133, 115, 95, 92, 97, 212, 81, 117, 70, 225, 199, + 123, 49, 84, 16, 84, 19, 134, 156, 33, 78, 195, 79, 191, 112, 44, 206, + 81, 249, 191, 4, 106, 159, 152, 246, 185, 246, 125, 7, 186, 106, 239, 25, + 144, 121, 78, 194, 199, 195, 218, 118, 189, 66, 2, 220, 105, 0, 77, 65, + 137, 55, 169, 82, 156, 126, 146, 139, 71, 44, 247, 210, 45, 171, 110, 252, + 221, 51, 80, 157, 164, 99, 10, 241, 175, 65, 32, 180, 254, 187, 89, 223, + 231, 227, 216, 197, 99, 217, 65, 187, 235, 152, 63, 74, 176, 36, 170, 236, + 134, 46, 98, 13, 108, 160, 126, 185, 245, 100, 96, 40, 240, 69, 171, 10, + 2, 141, 57, 105, 56, 82, 168, 46, 126, 161, 5, 219, 126, 1, 1, 165, + 92, 219, 81, 202, 86, 78, 174, 209, 195, 7, 142, 244, 119, 255, 115, 242, + 220, 11, 168, 135, 5, 71, 145, 137, 108, 10, 17, 30, 178, 142, 202, 147, + 24, 141, 161, 192, 79, 54, 62, 142, 239, 66, 209, 248, 101, 134, 83, 10, + 119, 121, 22, 240, 25, 227, 60, 180, 18, 46, 164, 105, 89, 30, 196, 167, + 206, 32, 32, 76, 54, 35, 10, 210, 170, 114, 127, 0, 216, 28, 71, 6, + 216, 15, 56, 201, 194, 246, 115, 182, 231, 202, 62, 218, 93, 252, 151, 125, + 48, 231, 133, 89, 67, 175, 88, 80, 25, 208, 80, 251, 226, 12, 4, 225, + 125, 37, 78, 202, 227, 212, 179, 219, 234, 223, 207, 188, 126, 214, 22, 59, + 134, 161, 108, 10, 115, 65, 40, 68, 211, 192, 129, 64, 163, 178, 183, 164, + 98, 212, 20, 146, 25, 16, 154, 29, 176, 107, 3, 15, 62, 226, 67, 119, + 189, 45, 123, 187, 83, 222, 206, 56, 135, 242, 121, 61, 220, 133, 171, 150, + 139, 221, 69, 112, 13, 183, 180, 76, 97, 122, 168, 79, 203, 136, 62, 161, + 138, 40, 253, 182, 3, 51, 229, 58, 195, 79, 191, 203, 248, 191, 180, 101, + 40, 189, 22, 127, 67, 139, 219, 213, 78, 11, 67, 215, 82, 41, 107, 54, + 143, 72, 223, 89, 246, 156, 91, 11, 157, 16, 225, 237, 213, 148, 187, 201, + 233, 101, 70, 211, 201, 113, 164, 185, 140, 169, 130, 42, 1, 222, 92, 59, + 66, 17, 108, 67, 197, 192, 251, 55, 203, 109, 189, 230, 131, 237, 215, 241, + 65, 148, 253, 241, 39, 141, 155, 148, 156, 244, 12, 68, 71, 109, 235, 241, + 4, 161, 177, 218, 114, 173, 113, 146, 11, 3, 219, 33, 141, 215, 62, 45, + 215, 184, 196, 97, 162, 250, 218, 110, 1, 190, 8, 67, 241, 94, 82, 196, + 64, 85, 118, 139, 240, 71, 67, 49, 241, 49, 129, 247, 44, 211, 46, 227, + 115, 140, 123, 192, 63, 82, 9, 155, 83, 167, 250, 70, 61, 66, 186, 217, + 46, 155, 128, 255, 232, 56, 224, 32, 254, 12, 204, 2, 85, 173, 20, 75, + 214, 73, 229, 18, 247, 145, 83, 241, 20, 245, 155, 15, 92, 111, 180, 101, + 179, 246, 5, 243, 112, 196, 44, 146, 16, 128, 155, 80, 106, 147, 110, 87, + 96, 17, 243, 247, 21, 87, 149, 78, 248, 20, 153, 249, 196, 11, 177, 96, + 227, 185, 136, 7, 244, 54, 177, 91, 192, 193, 111, 21, 159, 105, 143, 236, + 167, 215, 244, 121, 207, 245, 202, 161, 215, 45, 233, 32, 123, 220, 57, 34, + 171, 115, 37, 163, 75, 253, 140, 232, 51, 143, 204, 252, 146, 168, 85, 148, + 201, 161, 181, 231, 125, 44, 172, 79, 210, 12, 147, 82, 38, 254, 157, 225, + 167, 230, 182, 123, 63, 141, 146, 152, 136, 190, 80, 156, 163, 231, 33, 184, + 58, 200, 134, 28, 70, 202, 88, 195, 39, 224, 159, 154, 206, 183, 11, 96, + 102, 136, 26, 238, 179, 189, 226, 18, 30, 188, 148, 25, 3, 252, 154, 142, + 147, 145, 126, 11, 55, 1, 3, 108, 144, 55, 251, 167, 54, 127, 180, 216, + 77, 70, 138, 95, 166, 90, 48, 2, 211, 236, 235, 131, 107, 251, 91, 238, + 255, 0, 113, 41, 243, 14, 241, 252, 163, 99, 74, 25, 172, 87, 125, 36, + 203, 96, 189, 125, 222, 165, 138, 25, 76, 136, 67, 137, 161, 22, 232, 31, + 5, 96, 146, 214, 146, 21, 181, 198, 199, 34, 190, 63, 191, 201, 104, 116, + 123, 201, 64, 128, 84, 139, 86, 102, 244, 241, 162, 126, 4, 9, 132, 2, + 53, 113, 21, 1, 95, 7, 212, 123, 252, 100, 87, 78, 71, 28, 131, 135, + 183, 72, 196, 33, 66, 237, 12, 135, 58, 102, 69, 234, 214, 244, 57, 44, + 181, 120, 156, 218, 99, 146, 97, 15, 77, 113, 179, 142, 113, 226, 38, 72, + 128, 211, 160, 95, 52, 181, 30, 200, 64, 234, 8, 229, 150, 219, 225, 30, + 162, 223, 52, 242, 29, 31, 226, 91, 102, 235, 127, 213, 105, 123, 11, 172, + 190, 152, 59, 69, 1, 253, 126, 19, 145, 99, 33, 26, 198, 80, 74, 47, + 59, 77, 158, 60, 231, 51, 65, 145, 210, 232, 71, 100, 73, 71, 176, 239, + 42, 124, 176, 31, 254, 64, 223, 51, 195, 108, 165, 78, 202, 174, 212, 32, + 157, 58, 145, 133, 84, 230, 17, 206, 107, 72, 89, 129, 240, 179, 56, 231, + 218, 55, 236, 231, 122, 137, 50, 245, 171, 107, 223, 86, 17, 155, 68, 241, + 220, 120, 38, 95, 74, 110, 214, 202, 223, 60, 35, 120, 33, 79, 32, 58, + 77, 28, 121, 180, 99, 64, 201, 81, 156, 37, 28, 254, 219, 153, 74, 200, + 178, 70, 252, 140, 137, 127, 195, 238, 103, 228, 44, 96, 216, 12, 198, 246, + 206, 130, 67, 71, 129, 114, 145, 168, 64, 145, 128, 169, 169, 11, 28, 145, + 64, 144, 92, 206, 171, 135, 128, 121, 84, 142, 75, 37, 199, 208, 97, 243, + 114, 58, 152, 244, 201, 119, 76, 178, 3, 128, 185, 252, 146, 38, 165, 53, + 186, 175, 102, 81, 233, 115, 190, 227, 19, 31, 134, 132, 114, 24, 2, 21, + 249, 228, 128, 74, 119, 144, 74, 43, 168, 201, 131, 175, 254, 42, 103, 23, + 94, 138, 61, 40, 129, 252, 51, 80, 150, 135, 133, 55, 54, 122, 187, 93, + 42, 9, 154, 50, 93, 143, 241, 26, 80, 108, 7, 51, 144, 218, 129, 48, + 168, 66, 150, 108, 86, 127, 156, 232, 5, 54, 7, 182, 73, 210, 46, 115, + 84, 145, 113, 254, 195, 166, 106, 119, 116, 233, 154, 170, 185, 255, 99, 223, + 133, 115, 122, 10, 210, 76, 123, 92, 28, 159, 138, 133, 70, 126, 240, 215, + 36, 119, 180, 221, 156, 46, 89, 71, 1, 175, 247, 102, 107, 67, 136, 62, + 142, 197, 212, 50, 159, 107, 254, 44, 30, 59, 234, 51, 55, 35, 103, 170, + 231, 41, 111, 178, 14, 27, 77, 40, 43, 88, 199, 148, 211, 140, 17, 59, + 84, 182, 195, 92, 230, 109, 218, 165, 117, 39, 234, 195, 94, 70, 151, 202, + 167, 17, 179, 205, 213, 68, 102, 11, 120, 210, 150, 47, 150, 115, 186, 81, + 137, 53, 132, 36, 224, 107, 115, 100, 143, 118, 212, 239, 176, 139, 243, 36, + 235, 189, 48, 43, 25, 130, 143, 2, 165, 117, 173, 63, 189, 86, 180, 83, + 22, 204, 226, 141, 78, 199, 226, 195, 94, 183, 88, 103, 180, 205, 96, 254, + 235, 65, 144, 231, 11, 193, 111, 52, 129, 110, 125, 68, 42, 234, 138, 118, + 112, 69, 178, 191, 213, 115, 230, 221, 222, 97, 60, 187, 154, 161, 24, 25, + 147, 205, 69, 47, 45, 241, 84, 238, 249, 129, 6, 107, 126, 245, 187, 62, + 247, 159, 178, 6, 100, 80, 244, 229, 53, 83, 186, 208, 116, 164, 83, 217, + 76, 21, 191, 207, 44, 19, 21, 253, 153, 84, 92, 96, 41, 9, 10, 187, + 82, 155, 222, 146, 71, 130, 217, 44, 75, 51, 56, 119, 4, 77, 141, 46, + 0, 97, 157, 176, 42, 30, 102, 41, 39, 48, 191, 201, 226, 156, 80, 24, + 28, 109, 150, 215, 254, 211, 17, 87, 114, 111, 250, 7, 60, 233, 55, 121, + 139, 121, 167, 213, 0, 106, 85, 183, 122, 254, 65, 52, 95, 129, 197, 156, + 125, 235, 47, 46, 191, 44, 139, 244, 217, 239, 216, 228, 14, 234, 216, 19, + 13, 124, 221, 166, 60, 124, 187, 83, 242, 154, 57, 182, 125, 172, 123, 100, + 165, 156, 196, 254, 19, 73, 234, 83, 209, 242, 17, 54, 12, 115, 163, 148, + 32, 146, 41, 86, 171, 11, 77, 71, 162, 203, 42, 153, 71, 217, 254, 31, + 214, 184, 58, 41, 245, 132, 249, 54, 172, 163, 225, 203, 205, 52, 64, 105, + 110, 128, 162, 176, 118, 243, 173, 173, 69, 11, 98, 19, 183, 83, 247, 5, + 137, 91, 192, 122, 15, 151, 125, 192, 220, 207, 6, 118, 84, 8, 86, 196, + 88, 59, 246, 8, 250, 10, 27, 7, 233, 225, 220, 213, 222, 239, 138, 177, + 173, 63, 58, 16, 68, 113, 218, 216, 24, 25, 147, 176, 232, 249, 135, 194, + 5, 26, 37, 110, 251, 13, 178, 55, 28, 116, 84, 162, 145, 153, 117, 194, + 41, 16, 179, 64, 121, 52, 127, 232, 232, 53, 135, 212, 72, 122, 32, 112, + 152, 10, 241, 217, 107, 3, 99, 91, 115, 88, 107, 146, 120, 22, 156, 153, + 68, 104, 212, 39, 76, 144, 54, 58, 61, 91, 212, 96, 139, 35, 184, 37, + 17, 55, 223, 15, 75, 18, 55, 124, 232, 21, 10, 147, 24, 221, 23, 87, + 186, 27, 152, 51, 247, 112, 63, 56, 89, 180, 195, 67, 89, 105, 236, 102, + 235, 57, 17, 45, 151, 91, 186, 224, 171, 11, 149, 111, 102, 149, 50, 144, + 250, 243, 179, 20, 251, 203, 229, 228, 190, 33, 209, 254, 237, 112, 60, 222, + 179, 19, 224, 4, 78, 246, 239, 248, 80, 169, 180, 71, 190, 29, 178, 253, + 130, 207, 77, 202, 16, 108, 142, 201, 238, 135, 247, 155, 237, 187, 243, 139, + 247, 21, 141, 125, 213, 34, 106, 183, 4, 125, 40, 8, 104, 128, 73, 121, + 163, 122, 190, 121, 152, 45, 174, 52, 181, 139, 254, 242, 146, 36, 163, 183, + 147, 27, 234, 160, 222, 93, 232, 251, 153, 185, 158, 215, 9, 86, 49, 72, + 87, 154, 88, 169, 82, 186, 198, 240, 104, 92, 129, 217, 12, 124, 113, 206, + 117, 116, 149, 159, 149, 124, 219, 138, 96, 50, 177, 145, 244, 8, 232, 218, + 158, 22, 70, 31, 52, 226, 90, 7, 187, 135, 66, 35, 193, 62, 122, 72, + 201, 100, 66, 137, 236, 158, 187, 195, 107, 234, 27, 155, 187, 221, 131, 2, + 167, 165, 18, 225, 67, 72, 190, 63, 136, 69, 32, 185, 181, 234, 159, 57, + 4, 101, 127, 121, 3, 2, 235, 220, 44, 245, 160, 71, 64, 175, 55, 135, + 83, 250, 217, 239, 121, 81, 181, 160, 151, 70, 56, 101, 74, 169, 142, 167, + 10, 179, 233, 140, 156, 203, 110, 15, 95, 15, 8, 169, 164, 40, 43, 50, + 148, 216, 167, 161, 36, 142, 145, 126, 236, 167, 154, 120, 110, 239, 138, 53, + 152, 233, 115, 33, 203, 253, 249, 174, 176, 43, 0, 178, 120, 133, 211, 252, + 95, 221, 221, 185, 36, 145, 53, 15, 125, 26, 232, 42, 249, 86, 8, 205, + 183, 114, 81, 62, 187, 162, 4, 251, 26, 79, 159, 156, 42, 7, 83, 97, + 14, 124, 38, 252, 215, 34, 141, 252, 226, 61, 237, 252, 114, 117, 187, 21, + 53, 236, 151, 9, 147, 40, 68, 63, 10, 166, 84, 236, 0, 169, 196, 239, + 107, 214, 32, 53, 142, 172, 22, 245, 22, 154, 150, 105, 223, 5, 178, 48, + 151, 191, 251, 63, 50, 255, 54, 206, 221, 49, 249, 35, 133, 197, 248, 47, + 155, 185, 108, 172, 179, 104, 121, 72, 25, 83, 78, 205, 136, 136, 250, 47, + 68, 179, 166, 229, 237, 212, 214, 104, 191, 88, 159, 43, 30, 168, 89, 25, + 137, 79, 142, 7, 237, 19, 230, 87, 255, 20, 182, 27, 217, 197, 80, 45, + 119, 115, 241, 181, 96, 155, 160, 62, 57, 162, 103, 171, 196, 214, 243, 194, + 41, 223, 187, 22, 4, 157, 139, 4, 98, 193, 171, 27, 217, 8, 27, 100, + 222, 30, 235, 4, 127, 97, 243, 231, 102, 37, 47, 237, 58, 79, 189, 143, + 193, 144, 0, 150, 183, 0, 100, 29, 130, 166, 233, 150, 241, 61, 175, 23, + 56, 239, 24, 59, 143, 79, 27, 23, 124, 4, 9, 207, 73, 21, 181, 227, + 80, 149, 79, 226, 85, 110, 255, 126, 11, 66, 167, 203, 91, 50, 255, 189, + 91, 50, 79, 115, 160, 201, 112, 13, 25, 100, 68, 8, 218, 253, 185, 90, + 85, 79, 74, 27, 123, 23, 229, 57, 97, 91, 127, 106, 189, 186, 213, 74, + 233, 11, 137, 181, 51, 79, 108, 16, 145, 67, 82, 93, 245, 199, 182, 112, + 114, 208, 100, 151, 117, 222, 34, 187, 232, 137, 114, 251, 117, 217, 153, 37, + 215, 22, 113, 249, 198, 21, 184, 245, 107, 107, 27, 224, 2, 158, 165, 155, + 155, 104, 108, 215, 105, 154, 76, 171, 175, 245, 245, 206, 227, 85, 231, 208, + 127, 196, 191, 48, 150, 44, 38, 194, 191, 59, 10, 10, 175, 148, 162, 163, + 122, 167, 207, 145, 105, 234, 57, 199, 40, 112, 205, 98, 242, 238, 38, 68, + 192, 158, 91, 141, 80, 54, 12, 193, 215, 8, 201, 136, 185, 229, 109, 175, + 25, 245, 209, 147, 197, 233, 17, 80, 189, 150, 49, 218, 246, 78, 30, 112, + 64, 212, 109, 75, 232, 228, 171, 102, 239, 219, 152, 158, 217, 121, 43, 174, + 99, 82, 7, 113, 222, 107, 164, 30, 205, 236, 152, 19, 157, 60, 82, 165, + 34, 117, 23, 166, 185, 209, 212, 7, 250, 32, 167, 172, 234, 117, 139, 110, + 191, 14, 44, 158, 95, 115, 126, 115, 234, 209, 174, 95, 163, 117, 243, 203, + 182, 113, 182, 4, 33, 100, 143, 45, 225, 128, 69, 73, 183, 246, 91, 28, + 57, 20, 1, 175, 125, 128, 38, 4, 54, 93, 255, 28, 106, 122, 42, 104, + 35, 79, 242, 117, 75, 237, 149, 28, 178, 84, 224, 183, 116, 254, 120, 3, + 70, 154, 8, 57, 132, 86, 14, 119, 4, 130, 3, 155, 233, 177, 27, 28, + 233, 148, 205, 109, 29, 39, 33, 0, 160, 214, 129, 207, 180, 227, 131, 109, + 29, 136, 60, 47, 234, 99, 52, 57, 228, 87, 114, 138, 185, 19, 148, 152, + 114, 48, 12, 231, 182, 67, 228, 94, 253, 199, 34, 171, 238, 77, 59, 83, + 128, 137, 52, 74, 35, 236, 38, 181, 165, 106, 161, 12, 100, 76, 100, 237, + 69, 13, 211, 210, 117, 185, 178, 17, 231, 85, 134, 101, 66, 9, 71, 42, + 88, 125, 183, 106, 217, 38, 175, 131, 139, 75, 163, 134, 149, 70, 120, 146, + 156, 196, 151, 154, 242, 232, 163, 33, 206, 179, 123, 102, 249, 28, 11, 115, + 88, 20, 192, 244, 74, 33, 165, 176, 215, 142, 87, 229, 188, 139, 225, 192, + 111, 203, 55, 25, 241, 218, 22, 119, 121, 89, 69, 116, 214, 254, 94, 137, + 253, 168, 156, 155, 34, 150, 56, 126, 229, 79, 49, 150, 109, 99, 194, 179, + 40, 114, 63, 220, 161, 254, 73, 154, 211, 245, 21, 255, 63, 209, 45, 135, + 86, 234, 184, 213, 95, 28, 28, 244, 42, 66, 200, 83, 190, 81, 247, 24, + 153, 129, 180, 45, 159, 132, 4, 187, 171, 88, 178, 140, 143, 60, 212, 187, + 102, 125, 212, 66, 85, 133, 248, 58, 240, 126, 196, 7, 68, 71, 137, 202, + 116, 79, 137, 229, 156, 122, 69, 94, 146, 226, 198, 191, 116, 96, 33, 50, + 189, 32, 4, 5, 92, 116, 29, 122, 137, 140, 42, 199, 138, 59, 38, 48, + 178, 115, 216, 201, 225, 170, 183, 55, 248, 151, 58, 187, 184, 152, 106, 130, + 176, 52, 36, 73, 99, 77, 12, 166, 238, 52, 231, 86, 144, 91, 2, 248, + 246, 127, 5, 182, 201, 149, 205, 246, 73, 158, 98, 4, 20, 138, 51, 176, + 71, 169, 209, 237, 230, 100, 244, 243, 107, 80, 113, 246, 233, 115, 26, 175, + 72, 11, 38, 165, 68, 108, 163, 27, 38, 43, 246, 18, 153, 208, 118, 235, + 201, 225, 235, 17, 65, 53, 173, 72, 230, 232, 105, 215, 41, 180, 191, 61, + 31, 28, 214, 219, 29, 209, 90, 206, 232, 80, 22, 101, 237, 61, 105, 128, + 249, 224, 23, 242, 8, 250, 190, 130, 207, 148, 102, 166, 241, 67, 58, 8, + 61, 43, 58, 21, 148, 188, 40, 139, 116, 11, 79, 186, 85, 9, 240, 164, + 117, 238, 157, 59, 244, 184, 250, 69, 143, 88, 147, 126, 237, 37, 6, 159, + 130, 18, 72, 138, 251, 58, 136, 155, 92, 42, 173, 253, 171, 166, 57, 160, + 162, 211, 173, 241, 66, 121, 37, 176, 180, 140, 117, 240, 132, 181, 16, 234, + 173, 59, 98, 9, 123, 31, 18, 165, 45, 182, 89, 112, 130, 79, 53, 10, + 120, 252, 52, 114, 58, 57, 146, 87, 222, 154, 231, 215, 219, 84, 246, 85, + 57, 206, 180, 66, 125, 212, 226, 45, 212, 74, 132, 27, 185, 34, 150, 235, + 119, 218, 77, 70, 235, 171, 112, 123, 174, 87, 160, 89, 86, 219, 3, 47, + 39, 240, 116, 102, 70, 107, 31, 55, 102, 167, 4, 101, 119, 146, 176, 237, + 168, 123, 84, 118, 218, 112, 118, 52, 18, 56, 120, 216, 66, 187, 31, 12, + 205, 53, 119, 26, 225, 215, 195, 226, 2, 201, 75, 105, 65, 81, 45, 239, + 114, 182, 155, 135, 95, 153, 240, 143, 109, 109, 219, 218, 224, 26, 175, 35, + 86, 128, 209, 255, 71, 26, 86, 115, 22, 70, 167, 3, 105, 128, 160, 142, + 163, 149, 168, 112, 8, 12, 14, 119, 65, 43, 183, 105, 197, 156, 207, 226, + 231, 239, 48, 62, 4, 49, 169, 234, 123, 26, 164, 98, 119, 33, 170, 43, + 39, 6, 128, 15, 217, 209, 229, 109, 240, 180, 150, 169, 252, 118, 242, 240, + 108, 204, 24, 107, 199, 108, 184, 110, 208, 52, 175, 245, 241, 123, 90, 123, + 150, 211, 56, 75, 247, 140, 187, 53, 172, 174, 90, 223, 117, 128, 254, 97, + 235, 170, 193, 190, 34, 215, 109, 18, 109, 13, 118, 134, 45, 22, 100, 73, + 141, 199, 203, 124, 169, 191, 102, 108, 250, 201, 188, 39, 236, 74, 154, 159, + 170, 137, 69, 63, 82, 44, 177, 240, 178, 157, 53, 89, 6, 99, 5, 13, + 134, 169, 195, 121, 229, 179, 212, 123, 198, 131, 96, 250, 187, 94, 106, 51, + 219, 16, 147, 227, 108, 124, 240, 237, 172, 43, 83, 157, 124, 246, 118, 249, + 175, 43, 235, 221, 18, 24, 166, 127, 255, 210, 199, 57, 134, 73, 141, 254, + 219, 209, 19, 217, 36, 25, 104, 225, 133, 24, 3, 130, 62, 103, 148, 212, + 243, 122, 52, 213, 102, 26, 144, 227, 189, 143, 151, 230, 98, 87, 214, 147, + 110, 31, 43, 248, 142, 126, 199, 95, 170, 186, 67, 225, 208, 49, 50, 159, + 108, 174, 152, 118, 43, 193, 187, 13, 63, 141, 94, 118, 113, 200, 75, 165, + 117, 247, 53, 209, 151, 163, 241, 24, 23, 252, 149, 18, 16, 77, 69, 208, + 219, 254, 159, 220, 62, 99, 26, 31, 231, 88, 150, 219, 168, 151, 178, 181, + 234, 141, 124, 130, 37, 1, 21, 195, 96, 139, 179, 136, 145, 29, 159, 213, + 248, 10, 174, 213, 22, 180, 250, 251, 30, 42, 228, 139, 178, 90, 19, 228, + 100, 120, 205, 54, 6, 189, 213, 203, 193, 43, 218, 211, 27, 93, 76, 181, + 127, 159, 43, 96, 233, 249, 118, 252, 127, 59, 67, 82, 65, 48, 100, 170, + 227, 197, 141, 49, 153, 31, 189, 176, 102, 14, 101, 152, 242, 25, 251, 47, + 242, 67, 114, 61, 184, 29, 60, 163, 186, 19, 17, 36, 42, 76, 31, 246, + 195, 224, 206, 221, 89, 69, 218, 112, 148, 98, 60, 154, 28, 199, 206, 59, + 157, 199, 18, 214, 53, 217, 211, 254, 128, 220, 189, 96, 134, 57, 73, 152, + 41, 52, 0, 93, 23, 215, 124, 209, 63, 252, 134, 64, 224, 183, 197, 94, + 46, 214, 214, 233, 202, 211, 155, 236, 31, 238, 220, 132, 54, 88, 122, 140, + 146, 11, 88, 164, 238, 156, 72, 239, 225, 82, 157, 144, 27, 240, 5, 231, + 89, 25, 63, 50, 227, 219, 3, 5, 218, 125, 13, 151, 59, 40, 162, 211, + 79, 33, 157, 76, 245, 55, 229, 140, 88, 50, 221, 42, 52, 162, 106, 212, + 125, 187, 254, 0, 126, 156, 98, 149, 35, 94, 247, 215, 131, 86, 116, 176, + 3, 56, 30, 26, 138, 113, 71, 255, 77, 143, 52, 111, 20, 113, 47, 88, + 104, 110, 225, 164, 226, 8, 74, 180, 182, 183, 206, 215, 84, 12, 46, 61, + 177, 168, 102, 244, 93, 199, 243, 247, 214, 227, 131, 185, 103, 131, 49, 3, + 49, 18, 74, 111, 249, 150, 2, 113, 165, 221, 7, 93, 110, 59, 242, 246, + 243, 168, 45, 182, 45, 140, 19, 41, 72, 10, 164, 190, 17, 174, 216, 36, + 216, 3, 1, 198, 230, 150, 19, 0, 114, 10, 75, 166, 138, 161, 0, 113, + 132, 128, 116, 201, 147, 42, 63, 211, 56, 195, 45, 125, 69, 55, 177, 149, + 228, 7, 78, 217, 133, 35, 108, 182, 210, 185, 124, 187, 167, 95, 246, 202, + 121, 167, 61, 61, 239, 37, 153, 143, 109, 126, 42, 69, 174, 253, 132, 161, + 118, 14, 10, 7, 141, 92, 188, 60, 81, 174, 93, 28, 58, 223, 217, 119, + 84, 213, 230, 132, 248, 31, 47, 141, 88, 249, 28, 205, 19, 5, 183, 167, + 88, 177, 66, 242, 50, 66, 255, 31, 218, 182, 209, 12, 246, 151, 87, 252, + 211, 231, 32, 120, 95, 76, 180, 20, 124, 238, 190, 60, 165, 239, 207, 37, + 221, 115, 145, 126, 61, 51, 141, 54, 64, 219, 247, 164, 74, 19, 7, 93, + 27, 150, 115, 224, 228, 172, 232, 113, 6, 148, 40, 229, 228, 32, 17, 92, + 215, 75, 64, 50, 235, 127, 109, 127, 152, 99, 73, 55, 210, 245, 55, 37, + 236, 244, 136, 154, 177, 231, 119, 30, 187, 225, 83, 240, 237, 183, 80, 245, + 10, 129, 181, 156, 137, 27, 79, 97, 145, 78, 100, 127, 79, 224, 218, 244, + 49, 70, 225, 131, 138, 102, 32, 110, 123, 110, 49, 161, 246, 27, 99, 115, + 171, 159, 45, 44, 15, 108, 51, 173, 24, 4, 170, 76, 255, 41, 27, 0, + 27, 35, 61, 145, 246, 241, 138, 152, 47, 51, 2, 153, 171, 79, 81, 176, + 123, 63, 192, 74, 27, 243, 22, 51, 86, 243, 48, 24, 129, 162, 69, 218, + 102, 143, 135, 107, 52, 182, 189, 25, 142, 206, 227, 144, 140, 57, 124, 252, + 97, 157, 61, 55, 43, 76, 52, 197, 146, 154, 83, 0, 150, 16, 85, 76, + 230, 32, 23, 86, 31, 241, 251, 88, 183, 195, 242, 192, 181, 160, 229, 185, + 229, 186, 72, 219, 249, 142, 111, 178, 42, 163, 117, 93, 31, 171, 161, 227, + 194, 51, 36, 53, 116, 0, 233, 37, 150, 128, 144, 8, 168, 198, 68, 35, + 57, 148, 64, 207, 148, 64, 213, 174, 223, 174, 129, 171, 81, 132, 1, 90, + 208, 100, 105, 209, 10, 209, 228, 138, 169, 82, 197, 37, 172, 32, 222, 70, + 180, 78, 59, 234, 106, 250, 76, 237, 59, 173, 178, 212, 151, 107, 131, 245, + 14, 218, 71, 56, 187, 138, 74, 101, 15, 32, 18, 131, 21, 57, 6, 32, + 115, 75, 244, 119, 168, 158, 154, 147, 72, 143, 232, 51, 49, 181, 115, 27, + 96, 141, 93, 202, 36, 38, 23, 61, 150, 171, 239, 66, 13, 183, 126, 24, + 99, 175, 110, 189, 88, 170, 252, 139, 127, 179, 106, 243, 140, 208, 243, 110, + 145, 64, 161, 4, 191, 209, 211, 72, 135, 24, 121, 210, 109, 42, 134, 9, + 160, 241, 186, 161, 203, 85, 212, 3, 23, 228, 75, 147, 133, 9, 100, 65, + 195, 165, 252, 229, 177, 199, 170, 63, 194, 247, 76, 171, 66, 203, 193, 3, + 74, 91, 86, 31, 85, 185, 52, 27, 175, 175, 84, 137, 51, 233, 26, 52, + 16, 75, 185, 95, 35, 167, 251, 67, 83, 217, 9, 241, 43, 252, 76, 242, + 101, 115, 133, 173, 154, 251, 33, 116, 118, 243, 152, 63, 173, 153, 63, 75, + 90, 106, 203, 197, 141, 149, 127, 9, 133, 218, 223, 193, 62, 19, 48, 231, + 45, 146, 21, 164, 1, 42, 43, 187, 75, 88, 20, 39, 233, 165, 20, 76, + 26, 145, 226, 155, 106, 187, 26, 195, 23, 212, 49, 60, 145, 149, 37, 167, + 73, 106, 203, 228, 185, 223, 108, 12, 187, 239, 88, 126, 27, 154, 235, 203, + 207, 187, 1, 114, 12, 112, 238, 17, 185, 120, 227, 177, 242, 191, 10, 18, + 241, 143, 21, 239, 31, 150, 102, 60, 15, 167, 209, 64, 117, 237, 45, 45, + 217, 147, 32, 28, 98, 221, 12, 20, 2, 176, 213, 147, 95, 31, 176, 64, + 237, 55, 53, 44, 105, 249, 43, 111, 73, 162, 180, 4, 62, 66, 118, 36, + 215, 254, 183, 249, 170, 39, 21, 69, 147, 65, 105, 136, 232, 160, 174, 141, + 84, 222, 189, 33, 250, 197, 226, 170, 246, 127, 87, 25, 10, 181, 46, 151, + 216, 250, 227, 131, 115, 64, 217, 11, 190, 199, 122, 148, 242, 221, 46, 169, + 45, 54, 9, 90, 251, 94, 61, 211, 30, 67, 199, 115, 204, 4, 199, 203, + 109, 137, 60, 223, 206, 3, 144, 170, 215, 224, 72, 247, 128, 64, 147, 140, + 223, 125, 20, 67, 248, 253, 206, 5, 44, 72, 160, 33, 20, 166, 80, 123, + 194, 220, 16, 134, 206, 24, 66, 217, 177, 231, 223, 66, 251, 253, 235, 180, + 36, 205, 107, 173, 198, 108, 83, 120, 82, 128, 120, 245, 67, 23, 248, 203, + 28, 14, 75, 235, 117, 111, 34, 127, 39, 52, 169, 101, 28, 144, 123, 20, + 197, 116, 96, 141, 201, 246, 61, 101, 132, 127, 98, 178, 186, 139, 226, 132, + 55, 229, 116, 75, 43, 241, 119, 139, 104, 169, 215, 199, 226, 113, 178, 214, + 153, 159, 139, 208, 106, 136, 77, 149, 72, 248, 49, 179, 98, 110, 192, 105, + 128, 27, 245, 36, 215, 210, 187, 98, 45, 92, 51, 238, 57, 153, 113, 21, + 86, 147, 122, 138, 3, 70, 66, 84, 135, 96, 199, 23, 123, 105, 226, 81, + 171, 23, 228, 73, 234, 240, 50, 135, 108, 143, 140, 247, 26, 245, 43, 94, + 183, 180, 240, 235, 159, 127, 57, 119, 6, 34, 58, 112, 170, 62, 37, 57, + 171, 56, 223, 147, 98, 204, 183, 146, 154, 85, 172, 49, 76, 84, 231, 138, + 117, 46, 81, 57, 240, 43, 102, 130, 234, 208, 237, 88, 164, 124, 128, 104, + 167, 38, 88, 73, 7, 131, 234, 67, 4, 213, 8, 211, 84, 81, 197, 133, + 123, 247, 254, 101, 230, 68, 245, 220, 193, 152, 208, 91, 63, 109, 228, 184, + 117, 28, 114, 146, 98, 142, 195, 4, 139, 48, 186, 242, 211, 124, 175, 224, + 69, 38, 35, 14, 253, 245, 242, 184, 138, 4, 206, 221, 15, 125, 189, 97, + 127, 46, 212, 10, 55, 1, 69, 56, 31, 180, 245, 93, 175, 58, 220, 3, + 164, 88, 22, 74, 157, 113, 246, 189, 65, 97, 235, 189, 126, 106, 50, 120, + 180, 71, 120, 11, 200, 48, 19, 57, 236, 64, 234, 180, 243, 32, 228, 127, + 228, 253, 42, 20, 238, 109, 161, 67, 73, 52, 35, 126, 197, 5, 117, 12, + 86, 215, 168, 60, 159, 4, 74, 193, 92, 104, 190, 30, 185, 187, 153, 208, + 87, 245, 62, 200, 16, 204, 189, 141, 188, 226, 187, 144, 101, 51, 86, 204, + 26, 22, 246, 230, 176, 81, 195, 19, 126, 58, 91, 30, 204, 178, 248, 217, + 81, 155, 68, 145, 42, 9, 22, 68, 22, 107, 25, 86, 153, 225, 224, 143, + 128, 94, 164, 65, 168, 173, 178, 181, 97, 100, 159, 212, 164, 213, 75, 25, + 35, 225, 133, 5, 243, 65, 39, 158, 155, 153, 3, 81, 53, 165, 153, 52, + 237, 226, 122, 245, 248, 255, 60, 13, 2, 41, 202, 232, 184, 57, 152, 133, + 105, 159, 33, 220, 49, 135, 76, 198, 212, 70, 168, 43, 233, 168, 180, 88, + 139, 246, 219, 120, 12, 161, 238, 88, 228, 9, 77, 236, 129, 227, 73, 91, + 104, 222, 104, 205, 28, 140, 205, 167, 178, 222, 150, 197, 139, 205, 66, 245, + 48, 241, 80, 225, 218, 27, 159, 205, 64, 148, 107, 54, 46, 190, 61, 0, + 161, 228, 124, 123, 18, 170, 35, 46, 53, 61, 171, 154, 121, 253, 187, 158, + 102, 194, 132, 94, 49, 239, 86, 57, 205, 129, 185, 234, 50, 56, 219, 36, + 56, 77, 247, 160, 75, 239, 154, 122, 34, 34, 143, 66, 53, 20, 212, 246, + 3, 79, 229, 119, 50, 132, 221, 187, 208, 82, 149, 183, 151, 200, 181, 97, + 12, 4, 136, 233, 171, 247, 128, 211, 234, 122, 152, 140, 221, 82, 83, 98, + 185, 95, 122, 23, 120, 124, 112, 240, 39, 16, 49, 140, 225, 135, 88, 69, + 96, 125, 246, 99, 224, 165, 148, 178, 35, 63, 192, 217, 39, 153, 63, 32, + 109, 142, 224, 12, 132, 10, 55, 49, 140, 217, 141, 113, 10, 72, 92, 37, + 121, 96, 72, 35, 184, 70, 156, 225, 140, 110, 150, 24, 95, 209, 172, 140, + 187, 10, 154, 58, 113, 215, 254, 36, 101, 155, 5, 46, 249, 59, 238, 164, + 25, 212, 35, 5, 87, 45, 183, 124, 174, 6, 182, 241, 206, 128, 118, 190, + 239, 160, 140, 2, 149, 90, 185, 125, 192, 8, 75, 105, 184, 51, 2, 11, + 198, 85, 249, 100, 88, 73, 229, 189, 80, 81, 244, 167, 62, 110, 52, 13, + 254, 122, 144, 170, 206, 64, 239, 191, 0, 73, 235, 143, 120, 81, 33, 87, + 83, 154, 156, 163, 31, 172, 104, 196, 78, 144, 100, 3, 54, 202, 67, 177, + 217, 80, 207, 235, 48, 12, 127, 78, 116, 96, 238, 226, 97, 154, 97, 120, + 19, 33, 89, 14, 160, 149, 243, 246, 196, 219, 74, 113, 225, 92, 32, 216, + 10, 50, 176, 127, 113, 63, 157, 143, 190, 245, 94, 244, 103, 85, 143, 162, + 61, 177, 203, 240, 204, 55, 183, 226, 251, 205, 53, 25, 19, 197, 160, 34, + 42, 128, 169, 80, 11, 210, 133, 105, 128, 175, 107, 72, 222, 130, 95, 209, + 93, 161, 16, 35, 244, 178, 236, 100, 20, 129, 190, 118, 246, 108, 68, 206, + 105, 58, 91, 90, 149, 0, 168, 95, 115, 63, 54, 240, 7, 164, 186, 100, + 76, 81, 225, 58, 178, 14, 46, 79, 31, 226, 180, 34, 164, 191, 84, 22, + 244, 90, 105, 13, 83, 133, 230, 81, 45, 49, 157, 84, 22, 168, 167, 205, + 219, 123, 209, 80, 87, 205, 180, 152, 162, 225, 229, 142, 72, 250, 240, 134, + 185, 145, 112, 149, 25, 185, 198, 174, 213, 83, 145, 151, 228, 138, 96, 152, + 242, 251, 227, 53, 229, 136, 37, 147, 184, 141, 104, 221, 51, 219, 21, 93, + 42, 253, 183, 57, 203, 92, 7, 240, 82, 171, 103, 167, 115, 233, 175, 142, + 8, 112, 10, 56, 44, 192, 231, 79, 18, 8, 68, 128, 106, 121, 225, 149, + 30, 210, 173, 86, 240, 30, 138, 197, 89, 213, 63, 161, 106, 65, 141, 57, + 96, 102, 191, 28, 56, 9, 201, 3, 248, 113, 118, 51, 121, 247, 83, 135, + 51, 54, 14, 19, 49, 175, 59, 206, 112, 172, 155, 243, 75, 19, 154, 102, + 188, 11, 76, 198, 136, 11, 44, 154, 139, 48, 34, 194, 116, 170, 198, 127, + 132, 231, 200, 44, 61, 210, 93, 20, 159, 201, 183, 39, 78, 178, 225, 112, + 50, 254, 198, 200, 207, 18, 196, 209, 222, 252, 67, 56, 186, 71, 24, 210, + 30, 105, 32, 102, 99, 239, 195, 191, 131, 246, 65, 121, 91, 66, 112, 28, + 170, 67, 28, 144, 187, 46, 117, 97, 187, 240, 250, 118, 249, 68, 151, 248, + 219, 208, 103, 242, 166, 122, 220, 59, 50, 215, 90, 160, 15, 15, 96, 89, + 167, 87, 22, 253, 137, 202, 126, 145, 162, 171, 97, 181, 102, 50, 107, 230, + 31, 183, 133, 105, 23, 233, 228, 13, 247, 169, 79, 53, 76, 138, 29, 51, + 53, 221, 126, 199, 47, 153, 184, 183, 198, 109, 192, 203, 178, 26, 115, 177, + 118, 158, 181, 43, 48, 174, 195, 253, 43, 18, 172, 171, 101, 129, 255, 63, + 41, 49, 160, 15, 86, 108, 235, 87, 115, 36, 93, 46, 164, 152, 49, 31, + 137, 125, 174, 115, 196, 240, 117, 226, 183, 151, 73, 30, 75, 59, 61, 160, + 96, 157, 215, 246, 160, 136, 82, 95, 181, 13, 207, 158, 106, 81, 18, 27, + 182, 35, 249, 72, 148, 128, 15, 82, 68, 197, 0, 159, 149, 239, 34, 250, + 171, 70, 200, 219, 214, 18, 134, 14, 71, 69, 219, 145, 208, 125, 65, 232, + 201, 212, 148, 39, 208, 142, 54, 38, 32, 154, 124, 35, 76, 173, 240, 232, + 23, 74, 183, 118, 137, 244, 180, 149, 195, 198, 105, 25, 246, 236, 155, 88, + 230, 134, 32, 126, 183, 72, 127, 129, 139, 161, 224, 222, 127, 107, 201, 78, + 227, 207, 10, 48, 9, 199, 240, 176, 49, 165, 95, 200, 101, 89, 40, 229, + 28, 8, 41, 193, 173, 218, 63, 229, 216, 170, 82, 90, 162, 243, 0, 125, + 248, 79, 186, 228, 44, 197, 178, 58, 196, 251, 85, 19, 254, 130, 110, 78, + 91, 217, 146, 16, 90, 221, 6, 129, 173, 73, 56, 77, 72, 19, 8, 14, + 129, 84, 19, 88, 146, 252, 137, 165, 222, 7, 199, 107, 135, 13, 253, 137, + 180, 184, 240, 37, 238, 133, 135, 80, 170, 172, 60, 80, 94, 130, 246, 166, + 63, 181, 30, 103, 97, 138, 193, 148, 96, 82, 61, 47, 188, 230, 118, 65, + 74, 28, 123, 50, 73, 12, 187, 123, 129, 19, 95, 213, 61, 153, 85, 243, + 44, 195, 249, 250, 121, 175, 42, 187, 154, 233, 91, 217, 49, 130, 129, 172, + 250, 182, 203, 30, 93, 213, 217, 24, 28, 198, 4, 208, 61, 207, 108, 120, + 22, 39, 136, 252, 123, 15, 188, 34, 35, 177, 35, 134, 178, 221, 217, 22, + 51, 18, 22, 215, 47, 68, 120, 130, 0, 192, 242, 170, 170, 202, 220, 179, + 185, 81, 204, 10, 115, 181, 231, 246, 172, 38, 43, 145, 56, 171, 219, 34, + 17, 96, 165, 209, 53, 44, 68, 74, 236, 249, 192, 35, 204, 123, 56, 118, + 174, 172, 151, 249, 36, 21, 133, 119, 237, 232, 61, 125, 6, 124, 200, 62, + 68, 67, 40, 196, 202, 84, 213, 160, 237, 85, 249, 125, 41, 187, 126, 48, + 152, 124, 104, 211, 127, 96, 167, 184, 23, 161, 68, 106, 119, 224, 226, 148, + 234, 54, 155, 168, 186, 193, 167, 15, 242, 100, 82, 15, 205, 247, 34, 24, + 134, 152, 115, 132, 114, 196, 0, 136, 242, 73, 91, 35, 90, 4, 161, 138, + 163, 21, 16, 244, 60, 158, 199, 246, 233, 150, 10, 142, 248, 196, 224, 129, + 8, 158, 81, 11, 92, 96, 197, 23, 45, 104, 235, 250, 9, 31, 47, 153, + 116, 22, 170, 186, 150, 46, 214, 246, 75, 116, 4, 242, 147, 168, 177, 134, + 143, 149, 36, 139, 224, 127, 143, 167, 208, 115, 158, 250, 132, 4, 124, 204, + 99, 217, 239, 97, 5, 38, 50, 17, 176, 171, 96, 92, 88, 219, 195, 184, + 160, 158, 175, 10, 175, 33, 245, 28, 55, 56, 207, 47, 46, 114, 108, 196, + 101, 93, 39, 227, 183, 40, 40, 109, 121, 123, 90, 85, 162, 165, 227, 200, + 238, 136, 223, 36, 77, 179, 45, 156, 51, 95, 33, 15, 219, 71, 37, 98, + 141, 150, 179, 78, 217, 221, 130, 186, 155, 84, 146, 217, 210, 202, 91, 212, + 50, 129, 188, 203, 28, 213, 10, 230, 40, 47, 215, 77, 161, 88, 71, 56, + 82, 124, 130, 249, 70, 139, 142, 23, 78, 139, 252, 32, 223, 90, 214, 27, + 94, 23, 12, 240, 77, 145, 71, 172, 75, 235, 141, 83, 145, 50, 101, 166, + 87, 154, 179, 203, 27, 233, 169, 45, 28, 41, 211, 46, 144, 123, 62, 62, + 205, 178, 180, 89, 32, 194, 238, 151, 217, 164, 214, 241, 164, 96, 215, 46, + 141, 189, 86, 97, 143, 4, 227, 73, 20, 221, 238, 66, 3, 132, 135, 229, + 22, 60, 152, 102, 211, 20, 250, 225, 36, 212, 131, 182, 212, 216, 84, 141, + 133, 86, 163, 136, 107, 219, 8, 100, 189, 138, 217, 60, 131, 237, 64, 37, + 241, 85, 140, 47, 54, 75, 58, 76, 66, 104, 245, 201, 199, 236, 188, 71, + 30, 171, 233, 190, 81, 120, 166, 63, 237, 249, 233, 192, 5, 24, 231, 193, + 39, 99, 101, 108, 92, 109, 156, 211, 111, 87, 157, 130, 16, 58, 113, 47, + 101, 152, 60, 183, 37, 227, 52, 255, 213, 16, 112, 234, 223, 197, 101, 73, + 120, 94, 60, 158, 82, 227, 131, 13, 4, 167, 78, 126, 120, 154, 26, 246, + 35, 145, 40, 150, 7, 208, 243, 100, 68, 89, 200, 139, 138, 121, 37, 28, + 35, 197, 227, 79, 19, 130, 171, 91, 116, 57, 153, 140, 217, 236, 7, 180, + 221, 226, 163, 199, 158, 131, 200, 37, 48, 41, 157, 175, 139, 71, 53, 172, + 113, 159, 133, 47, 139, 113, 157, 40, 88, 44, 115, 105, 104, 219, 211, 18, + 164, 170, 127, 5, 178, 115, 181, 143, 30, 173, 6, 186, 183, 45, 56, 94, + 252, 210, 171, 154, 10, 17, 34, 153, 4, 11, 176, 85, 144, 114, 36, 247, + 34, 67, 187, 69, 164, 168, 120, 82, 186, 46, 15, 147, 105, 48, 76, 235, + 15, 218, 86, 160, 19, 220, 119, 241, 103, 252, 196, 58, 74, 131, 214, 109, + 17, 175, 75, 203, 167, 17, 60, 52, 251, 130, 55, 184, 165, 83, 225, 231, + 184, 208, 196, 88, 70, 8, 3, 43, 78, 107, 158, 180, 130, 248, 194, 16, + 46, 54, 100, 98, 121, 67, 185, 17, 181, 210, 5, 15, 178, 196, 80, 220, + 28, 103, 220, 231, 167, 10, 122, 225, 194, 118, 157, 192, 195, 205, 130, 253, + 94, 246, 177, 74, 149, 90, 120, 188, 230, 48, 77, 168, 50, 76, 130, 136, + 200, 219, 209, 192, 20, 10, 193, 97, 205, 136, 98, 117, 128, 170, 198, 220, + 218, 180, 178, 186, 150, 227, 196, 161, 4, 244, 124, 31, 85, 243, 34, 78, + 187, 226, 164, 167, 122, 56, 114, 232, 140, 189, 160, 19, 184, 223, 165, 202, + 86, 210, 102, 183, 50, 30, 109, 134, 23, 102, 171, 130, 93, 106, 2, 117, + 80, 82, 197, 193, 247, 137, 255, 255, 127, 38, 13, 82, 103, 51, 179, 220, + 133, 247, 104, 152, 160, 229, 160, 214, 152, 157, 87, 183, 82, 43, 36, 19, + 80, 192, 122, 186, 201, 116, 190, 220, 131, 228, 153, 197, 212, 112, 233, 124, + 114, 212, 106, 195, 129, 141, 204, 238, 98, 247, 90, 244, 23, 118, 2, 168, + 71, 48, 223, 253, 187, 16, 204, 230, 46, 221, 30, 243, 27, 129, 155, 210, + 159, 84, 56, 212, 197, 131, 174, 59, 85, 108, 80, 36, 31, 210, 71, 228, + 254, 171, 67, 129, 154, 175, 245, 140, 11, 167, 43, 69, 231, 227, 91, 183, + 133, 108, 4, 151, 128, 64, 243, 215, 74, 160, 186, 217, 38, 28, 186, 75, + 178, 151, 214, 5, 49, 158, 242, 126, 91, 249, 88, 156, 110, 124, 205, 125, + 227, 19, 235, 172, 103, 200, 190, 121, 169, 140, 118, 156, 21, 152, 34, 31, + 235, 46, 191, 107, 37, 109, 135, 112, 195, 9, 245, 43, 96, 232, 74, 8, + 193, 131, 70, 140, 180, 204, 219, 243, 72, 70, 16, 11, 227, 0, 27, 252, + 142, 183, 199, 103, 114, 149, 221, 235, 69, 92, 245, 9, 227, 43, 173, 139, + 119, 85, 104, 214, 84, 126, 244, 243, 122, 14, 164, 185, 104, 176, 55, 133, + 44, 28, 208, 232, 50, 71, 32, 78, 200, 95, 153, 70, 82, 243, 91, 164, + 64, 159, 173, 244, 103, 78, 29, 218, 209, 124, 118, 153, 42, 69, 240, 237, + 228, 33, 155, 17, 61, 27, 233, 171, 6, 240, 48, 113, 243, 134, 207, 120, + 216, 61, 188, 247, 231, 185, 163, 43, 140, 138, 235, 132, 219, 47, 38, 93, + 205, 6, 247, 195, 200, 79, 87, 111, 210, 54, 222, 179, 108, 163, 253, 22, + 22, 101, 180, 6, 61, 41, 91, 95, 237, 186, 166, 110, 225, 139, 205, 146, + 41, 133, 153, 114, 63, 48, 110, 208, 168, 38, 233, 141, 23, 136, 236, 22, + 220, 14, 62, 224, 46, 20, 193, 181, 107, 14, 234, 156, 234, 108, 30, 112, + 235, 126, 237, 189, 252, 240, 240, 3, 175, 210, 85, 35, 230, 115, 219, 184, + 173, 48, 84, 250, 52, 113, 44, 187, 173, 253, 153, 177, 32, 127, 98, 100, + 180, 211, 71, 146, 82, 1, 69, 200, 165, 198, 121, 133, 232, 0, 237, 157, + 169, 31, 134, 106, 243, 245, 16, 228, 53, 133, 143, 255, 123, 175, 19, 10, + 98, 117, 180, 38, 50, 190, 63, 70, 106, 8, 221, 78, 66, 129, 190, 181, + 165, 119, 242, 101, 19, 18, 181, 91, 223, 30, 93, 253, 74, 242, 112, 139, + 30, 121, 25, 100, 144, 32, 212, 143, 3, 96, 134, 113, 193, 190, 51, 8, + 60, 108, 88, 168, 142, 47, 217, 173, 44, 207, 174, 161, 237, 179, 147, 4, + 30, 5, 177, 202, 43, 239, 15, 135, 44, 216, 10, 183, 63, 27, 159, 195, + 56, 238, 95, 213, 45, 44, 252, 4, 101, 233, 38, 88, 66, 126, 149, 196, + 87, 211, 55, 38, 17, 92, 26, 76, 156, 183, 136, 154, 166, 219, 125, 10, + 88, 240, 97, 14, 86, 67, 4, 74, 236, 71, 72, 10, 49, 18, 158, 148, + 128, 15, 241, 17, 9, 236, 243, 22, 116, 160, 65, 166, 34, 113, 76, 41, + 100, 153, 184, 22, 62, 252, 220, 47, 180, 124, 103, 242, 104, 13, 244, 136, + 33, 146, 33, 176, 31, 159, 235, 29, 221, 255, 182, 90, 183, 158, 186, 155, + 85, 137, 173, 129, 71, 91, 147, 17, 30, 240, 214, 110, 79, 64, 21, 129, + 97, 109, 253, 198, 203, 116, 235, 89, 166, 151, 116, 106, 194, 27, 51, 177, + 23, 119, 199, 227, 50, 143, 129, 234, 188, 217, 9, 136, 48, 115, 5, 252, + 241, 195, 116, 239, 68, 176, 55, 121, 2, 38, 229, 224, 94, 204, 200, 115, + 84, 235, 131, 172, 242, 56, 208, 41, 21, 36, 113, 156, 137, 6, 225, 132, + 4, 181, 193, 84, 10, 213, 155, 150, 72, 127, 23, 107, 255, 105, 250, 61, + 234, 211, 225, 169, 93, 63, 138, 95, 201, 74, 208, 99, 119, 184, 219, 62, + 86, 163, 142, 35, 24, 86, 92, 224, 53, 84, 57, 101, 113, 76, 26, 78, + 174, 49, 28, 234, 153, 240, 27, 114, 87, 133, 130, 78, 66, 144, 205, 152, + 171, 169, 136, 219, 142, 223, 145, 149, 196, 6, 167, 109, 52, 188, 0, 98, + 242, 254, 184, 129, 250, 63, 244, 10, 97, 188, 7, 137, 183, 165, 68, 91, + 26, 188, 230, 246, 227, 12, 217, 170, 224, 119, 135, 243, 149, 88, 67, 23, + 117, 173, 130, 164, 233, 244, 251, 11, 123, 57, 80, 111, 249, 146, 231, 213, + 158, 26, 236, 250, 213, 228, 117, 251, 101, 128, 8, 241, 251, 36, 40, 149, + 148, 60, 146, 48, 104, 121, 163, 233, 2, 24, 10, 21, 93, 137, 124, 8, + 115, 220, 255, 107, 153, 105, 6, 255, 32, 160, 96, 74, 84, 184, 31, 155, + 118, 206, 58, 131, 111, 150, 137, 145, 22, 45, 138, 211, 118, 151, 248, 189, + 64, 82, 222, 9, 137, 114, 59, 89, 77, 249, 245, 195, 146, 198, 43, 209, + 186, 151, 121, 136, 170, 81, 53, 43, 126, 15, 62, 88, 171, 206, 232, 34, + 99, 52, 6, 22, 126, 140, 32, 181, 122, 253, 230, 127, 211, 254, 61, 254, + 108, 114, 38, 214, 164, 244, 87, 243, 187, 185, 57, 105, 24, 244, 59, 254, + 92, 143, 235, 38, 70, 177, 126, 123, 61, 243, 45, 127, 76, 127, 39, 45, + 254, 239, 67, 221, 24, 81, 24, 130, 247, 106, 239, 93, 18, 57, 242, 4, + 223, 131, 86, 249, 241, 81, 149, 230, 154, 17, 14, 179, 194, 234, 17, 85, + 188, 33, 162, 62, 73, 157, 253, 248, 111, 97, 205, 47, 74, 223, 192, 185, + 212, 153, 240, 156, 104, 64, 46, 209, 146, 56, 27, 21, 184, 95, 107, 95, + 101, 243, 133, 146, 194, 240, 51, 109, 158, 225, 18, 80, 66, 4, 79, 252, + 174, 187, 55, 230, 54, 51, 42, 87, 34, 159, 155, 184, 118, 167, 150, 46, + 32, 156, 244, 124, 222, 84, 247, 12, 231, 119, 237, 135, 225, 227, 97, 178, + 37, 208, 112, 126, 32, 227, 60, 239, 194, 183, 169, 208, 221, 250, 180, 56, + 137, 67, 153, 170, 242, 54, 55, 48, 219, 79, 106, 249, 250, 56, 130, 184, + 43, 56, 114, 175, 122, 249, 107, 188, 63, 169, 25, 43, 68, 61, 246, 47, + 191, 117, 150, 7, 163, 144, 42, 186, 5, 195, 11, 68, 215, 219, 87, 213, + 42, 84, 99, 37, 29, 78, 34, 180, 131, 15, 171, 186, 225, 163, 204, 225, + 72, 198, 227, 122, 245, 4, 133, 40, 134, 17, 61, 112, 55, 159, 37, 118, + 112, 173, 210, 126, 9, 23, 209, 65, 14, 109, 16, 247, 254, 45, 170, 33, + 143, 35, 107, 134, 51, 132, 135, 226, 40, 112, 156, 122, 5, 31, 37, 113, + 24, 1, 153, 3, 180, 227, 249, 172, 93, 20, 79, 126, 42, 254, 100, 80, + 86, 180, 123, 71, 213, 32, 178, 28, 63, 75, 177, 246, 25, 119, 33, 236, + 194, 31, 94, 169, 97, 96, 42, 29, 165, 234, 199, 12, 76, 8, 242, 229, + 160, 130, 169, 76, 120, 159, 25, 18, 36, 182, 222, 210, 105, 251, 2, 40, + 111, 212, 249, 119, 48, 137, 50, 71, 146, 216, 47, 18, 60, 194, 18, 119, + 197, 216, 84, 170, 143, 241, 61, 207, 206, 238, 51, 39, 145, 171, 81, 108, + 64, 0, 229, 83, 190, 81, 149, 27, 77, 44, 34, 134, 178, 250, 9, 244, + 128, 175, 124, 28, 41, 116, 254, 30, 162, 88, 207, 231, 222, 155, 224, 234, + 201, 56, 119, 191, 190, 158, 195, 16, 153, 152, 99, 244, 60, 207, 205, 133, + 34, 101, 0, 104, 144, 141, 121, 168, 44, 40, 234, 49, 35, 136, 39, 242, + 14, 198, 188, 124, 161, 135, 113, 180, 68, 218, 10, 47, 223, 190, 0, 238, + 109, 149, 149, 25, 14, 218, 109, 85, 106, 125, 45, 29, 63, 122, 74, 184, + 39, 153, 72, 81, 69, 212, 62, 80, 161, 110, 103, 56, 254, 7, 198, 201, + 47, 202, 145, 147, 115, 7, 252, 21, 157, 211, 102, 40, 117, 116, 41, 110, + 189, 45, 41, 128, 46, 18, 40, 228, 43, 159, 202, 90, 114, 78, 193, 9, + 237, 172, 59, 89, 50, 218, 47, 142, 139, 118, 146, 201, 8, 158, 116, 71, + 133, 105, 177, 199, 24, 202, 219, 64, 136, 101, 162, 11, 225, 13, 60, 217, + 13, 125, 9, 38, 224, 90, 78, 166, 145, 101, 167, 132, 24, 58, 73, 19, + 2, 185, 83, 148, 110, 133, 191, 76, 71, 18, 168, 103, 0, 123, 195, 39, + 41, 243, 215, 62, 38, 156, 101, 42, 144, 43, 125, 154, 46, 152, 74, 242, + 251, 158, 180, 189, 228, 165, 64, 75, 220, 184, 160, 9, 23, 57, 138, 16, + 88, 240, 5, 234, 106, 188, 171, 120, 55, 203, 43, 72, 33, 67, 129, 26, + 242, 128, 89, 144, 226, 129, 58, 143, 110, 185, 216, 158, 238, 175, 34, 121, + 59, 49, 76, 178, 81, 88, 181, 23, 219, 66, 1, 228, 34, 143, 250, 41, + 77, 7, 245, 65, 3, 203, 53, 144, 140, 194, 71, 27, 10, 175, 218, 149, + 242, 213, 150, 9, 199, 22, 202, 155, 5, 44, 23, 111, 102, 5, 150, 32, + 62, 31, 220, 1, 129, 151, 109, 27, 215, 54, 235, 104, 157, 123, 8, 89, + 94, 161, 197, 0, 163, 75, 124, 41, 240, 192, 109, 9, 202, 124, 25, 82, + 95, 243, 170, 63, 91, 248, 4, 63, 47, 208, 243, 61, 85, 62, 107, 32, + 87, 19, 208, 87, 120, 234, 108, 244, 44, 158, 238, 91, 185, 219, 105, 13, + 254, 85, 208, 93, 148, 144, 160, 98, 237, 72, 27, 59, 119, 22, 99, 52, + 193, 190, 57, 171, 46, 247, 180, 126, 30, 16, 200, 88, 35, 212, 215, 253, + 218, 25, 96, 40, 44, 53, 29, 129, 153, 154, 197, 238, 84, 201, 244, 106, + 184, 178, 127, 54, 198, 60, 160, 98, 4, 229, 110, 220, 225, 26, 254, 238, + 123, 69, 248, 222, 43, 122, 207, 63, 166, 246, 171, 129, 231, 7, 89, 132, + 245, 76, 55, 174, 184, 93, 139, 221, 250, 11, 86, 239, 248, 14, 98, 226, + 66, 146, 45, 59, 106, 78, 6, 253, 6, 128, 53, 174, 7, 36, 100, 130, + 22, 47, 157, 147, 27, 31, 15, 97, 122, 46, 137, 84, 126, 104, 48, 217, + 236, 131, 51, 253, 147, 23, 35, 133, 43, 183, 124, 197, 150, 85, 170, 39, + 96, 227, 44, 130, 51, 83, 224, 22, 177, 39, 65, 125, 98, 28, 162, 56, + 25, 112, 81, 50, 28, 118, 184, 45, 236, 226, 87, 117, 111, 219, 157, 34, + 224, 77, 68, 59, 91, 80, 177, 178, 188, 203, 247, 133, 130, 15, 61, 125, + 252, 18, 201, 87, 157, 158, 47, 5, 151, 104, 231, 127, 161, 154, 172, 224, + 74, 95, 195, 121, 175, 200, 18, 26, 240, 194, 222, 85, 189, 238, 106, 136, + 195, 28, 170, 10, 115, 25, 236, 203, 127, 254, 103, 79, 175, 57, 159, 102, + 193, 106, 136, 130, 195, 16, 19, 14, 240, 130, 74, 217, 154, 5, 217, 88, + 21, 113, 205, 138, 241, 209, 39, 255, 182, 100, 41, 243, 199, 191, 7, 123, + 185, 7, 186, 28, 32, 71, 236, 16, 220, 222, 5, 122, 74, 55, 95, 19, + 230, 127, 201, 130, 180, 143, 142, 149, 229, 43, 81, 95, 32, 138, 165, 42, + 136, 231, 106, 34, 90, 135, 60, 60, 105, 191, 50, 195, 62, 230, 189, 100, + 41, 110, 61, 204, 139, 237, 185, 208, 136, 61, 249, 12, 20, 230, 48, 141, + 65, 17, 204, 126, 215, 73, 77, 129, 49, 230, 39, 247, 222, 109, 50, 151, + 255, 246, 141, 254, 233, 117, 156, 172, 113, 74, 72, 133, 218, 227, 4, 192, + 27, 185, 21, 99, 61, 34, 52, 112, 74, 18, 149, 38, 195, 43, 154, 8, + 16, 189, 142, 139, 167, 137, 2, 155, 165, 1, 255, 158, 107, 131, 141, 112, + 87, 102, 97, 12, 228, 30, 143, 60, 14, 238, 183, 145, 88, 116, 187, 64, + 138, 136, 138, 24, 16, 241, 126, 37, 103, 99, 203, 164, 198, 129, 140, 189, + 18, 178, 241, 154, 7, 81, 8, 75, 196, 131, 121, 19, 52, 90, 125, 71, + 179, 8, 102, 149, 117, 88, 2, 58, 115, 41, 254, 118, 205, 28, 244, 153, + 79, 179, 136, 194, 59, 55, 233, 48, 87, 218, 151, 218, 172, 109, 72, 156, + 112, 175, 129, 111, 124, 151, 112, 69, 175, 237, 175, 208, 35, 15, 70, 189, + 245, 118, 229, 51, 121, 237, 106, 57, 190, 157, 42, 37, 107, 108, 240, 142, + 180, 123, 58, 243, 99, 76, 153, 94, 235, 148, 3, 146, 198, 250, 3, 176, + 73, 105, 64, 3, 129, 155, 69, 66, 114, 55, 53, 31, 200, 171, 9, 127, + 227, 81, 238, 0, 29, 54, 79, 184, 213, 44, 21, 21, 106, 118, 193, 193, + 132, 216, 89, 39, 107, 40, 29, 198, 229, 184, 123, 32, 225, 148, 78, 40, + 236, 108, 100, 112, 139, 33, 176, 201, 41, 56, 180, 87, 100, 161, 247, 181, + 48, 215, 32, 88, 3, 2, 69, 189, 162, 185, 155, 129, 131, 151, 170, 201, + 203, 192, 141, 27, 38, 21, 174, 100, 48, 138, 216, 113, 123, 137, 161, 92, + 153, 129, 184, 21, 205, 18, 190, 184, 189, 57, 130, 168, 67, 161, 16, 207, + 223, 35, 254, 40, 169, 65, 104, 178, 164, 88, 198, 40, 58, 221, 211, 96, + 91, 98, 147, 157, 193, 121, 211, 28, 185, 217, 84, 58, 236, 70, 181, 35, + 58, 27, 111, 52, 213, 103, 93, 154, 18, 60, 201, 180, 29, 28, 85, 126, + 170, 190, 231, 64, 27, 191, 83, 158, 125, 124, 43, 172, 198, 25, 151, 108, + 116, 7, 164, 114, 92, 215, 197, 222, 31, 231, 41, 112, 42, 172, 207, 164, + 87, 123, 138, 156, 78, 44, 131, 127, 155, 114, 138, 219, 52, 223, 150, 230, + 94, 165, 103, 45, 139, 238, 161, 208, 117, 178, 225, 67, 90, 90, 110, 176, + 20, 110, 4, 189, 194, 138, 12, 168, 150, 181, 139, 54, 241, 243, 87, 19, + 136, 251, 68, 1, 239, 85, 161, 139, 67, 117, 239, 162, 214, 96, 205, 66, + 79, 13, 47, 16, 72, 171, 33, 246, 93, 197, 65, 115, 108, 87, 83, 116, + 49, 66, 34, 18, 101, 65, 24, 178, 147, 34, 61, 242, 51, 246, 191, 249, + 164, 200, 210, 150, 146, 46, 157, 137, 147, 161, 25, 101, 217, 142, 125, 241, + 73, 115, 83, 86, 208, 167, 233, 77, 109, 89, 197, 219, 108, 206, 54, 99, + 113, 101, 77, 41, 251, 24, 203, 179, 28, 109, 62, 248, 113, 197, 82, 35, + 89, 132, 11, 184, 194, 237, 142, 71, 81, 173, 36, 220, 103, 66, 254, 78, + 252, 105, 211, 89, 149, 132, 218, 43, 45, 77, 64, 137, 248, 238, 145, 172, + 64, 78, 123, 225, 161, 166, 202, 94, 210, 227, 36, 254, 153, 230, 23, 21, + 82, 125, 167, 115, 10, 25, 141, 144, 226, 25, 151, 22, 157, 162, 2, 250, + 16, 161, 48, 111, 121, 9, 191, 229, 41, 136, 83, 163, 165, 10, 195, 34, + 56, 145, 166, 99, 184, 180, 180, 159, 95, 110, 17, 46, 227, 245, 97, 207, + 27, 113, 121, 55, 196, 29, 248, 171, 108, 250, 236, 1, 31, 108, 15, 34, + 233, 32, 250, 127, 67, 159, 151, 145, 5, 171, 219, 102, 159, 137, 231, 130, + 229, 177, 209, 253, 150, 217, 76, 62, 111, 42, 25, 152, 169, 83, 245, 164, + 127, 61, 128, 35, 234, 8, 69, 152, 103, 107, 18, 98, 101, 214, 205, 136, + 68, 165, 54, 48, 189, 59, 29, 254, 128, 255, 249, 46, 23, 246, 29, 131, + 185, 27, 160, 235, 16, 52, 232, 247, 100, 230, 137, 91, 111, 48, 202, 31, + 126, 167, 162, 45, 159, 66, 215, 176, 32, 5, 255, 82, 108, 31, 184, 89, + 6, 73, 8, 209, 86, 202, 122, 111, 132, 39, 140, 160, 74, 148, 254, 21, + 33, 80, 180, 165, 241, 182, 74, 205, 243, 194, 17, 216, 113, 8, 239, 190, + 34, 158, 31, 58, 223, 249, 51, 74, 174, 191, 157, 185, 12, 98, 190, 135, + 91, 198, 25, 221, 76, 118, 88, 240, 184, 188, 70, 92, 36, 208, 124, 43, + 228, 200, 86, 193, 178, 251, 115, 233, 240, 11, 134, 91, 230, 141, 195, 161, + 255, 12, 103, 85, 187, 84, 129, 202, 48, 85, 155, 242, 226, 185, 109, 126, + 2, 8, 174, 221, 203, 67, 182, 52, 114, 243, 219, 32, 89, 183, 125, 18, + 209, 200, 99, 116, 123, 185, 17, 250, 250, 223, 129, 221, 147, 249, 142, 238, + 25, 230, 85, 85, 141, 248, 144, 13, 241, 3, 10, 253, 74, 96, 82, 115, + 210, 221, 17, 79, 213, 119, 27, 192, 55, 41, 161, 125, 167, 87, 45, 10, + 246, 22, 76, 245, 83, 4, 160, 242, 62, 221, 89, 206, 80, 235, 33, 34, + 81, 125, 28, 117, 233, 167, 89, 6, 132, 138, 130, 88, 227, 245, 44, 138, + 180, 42, 215, 4, 177, 9, 167, 135, 173, 234, 185, 119, 100, 108, 4, 237, + 145, 52, 227, 61, 231, 130, 77, 97, 204, 175, 136, 225, 27, 29, 36, 142, + 151, 129, 170, 105, 233, 88, 57, 122, 219, 60, 16, 70, 253, 218, 123, 188, + 49, 210, 121, 115, 150, 249, 213, 246, 76, 2, 197, 196, 24, 169, 143, 175, + 230, 138, 32, 81, 191, 13, 166, 211, 252, 110, 84, 221, 244, 13, 45, 116, + 242, 123, 18, 153, 163, 187, 46, 33, 28, 160, 219, 179, 85, 166, 2, 125, + 92, 99, 147, 61, 4, 200, 245, 135, 172, 187, 4, 101, 102, 85, 79, 168, + 53, 222, 129, 150, 252, 253, 252, 45, 39, 64, 33, 104, 69, 239, 180, 71, + 234, 177, 245, 185, 59, 238, 88, 65, 58, 156, 84, 238, 150, 46, 236, 65, + 229, 33, 221, 168, 102, 249, 163, 155, 36, 189, 54, 211, 154, 247, 69, 45, + 47, 140, 119, 63, 143, 129, 163, 38, 120, 88, 216, 66, 117, 118, 176, 93, + 153, 42, 129, 198, 45, 203, 26, 150, 43, 17, 53, 104, 196, 82, 234, 59, + 129, 81, 14, 104, 229, 8, 204, 187, 8, 168, 112, 18, 211, 154, 195, 181, + 87, 241, 234, 148, 68, 229, 231, 23, 134, 14, 97, 119, 22, 48, 123, 17, + 115, 105, 180, 124, 135, 51, 177, 104, 187, 23, 210, 76, 161, 8, 36, 57, + 218, 252, 142, 236, 154, 178, 119, 129, 189, 255, 208, 56, 25, 70, 68, 50, + 57, 172, 77, 154, 163, 80, 33, 180, 118, 57, 105, 97, 5, 50, 158, 185, + 226, 119, 237, 163, 47, 79, 233, 114, 160, 246, 93, 238, 197, 217, 240, 55, + 121, 37, 138, 104, 245, 181, 30, 133, 129, 94, 97, 31, 188, 121, 119, 74, + 227, 167, 196, 194, 108, 185, 63, 242, 0, 224, 8, 162, 49, 173, 57, 250, + 12, 113, 238, 241, 0, 180, 180, 198, 57, 180, 248, 243, 214, 122, 103, 81, + 205, 243, 232, 213, 39, 122, 142, 107, 4, 63, 123, 147, 22, 78, 174, 200, + 33, 27, 16, 76, 139, 230, 32, 101, 246, 228, 246, 89, 15, 30, 11, 87, + 174, 70, 195, 104, 14, 26, 209, 149, 19, 254, 121, 62, 186, 224, 56, 247, + 10, 237, 102, 83, 215, 211, 22, 123, 161, 52, 251, 122, 142, 228, 191, 93, + 151, 174, 176, 166, 64, 184, 254, 113, 140, 214, 109, 159, 126, 201, 95, 245, + 167, 180, 165, 106, 61, 83, 143, 239, 68, 254, 0, 201, 237, 162, 231, 108, + 152, 131, 248, 39, 149, 131, 80, 224, 41, 14, 157, 96, 16, 251, 139, 15, + 153, 45, 29, 84, 116, 154, 221, 234, 127, 39, 10, 244, 3, 92, 154, 93, + 125, 209, 252, 144, 73, 139, 47, 93, 98, 78, 7, 61, 173, 117, 46, 155, + 73, 76, 127, 202, 5, 223, 113, 215, 86, 54, 82, 0, 105, 16, 52, 226, + 140, 232, 53, 23, 76, 117, 212, 139, 183, 112, 95, 162, 174, 153, 104, 4, + 241, 133, 159, 188, 4, 147, 92, 125, 133, 104, 26, 241, 130, 13, 239, 96, + 235, 36, 195, 74, 193, 126, 54, 27, 55, 190, 97, 44, 26, 106, 31, 76, + 244, 174, 179, 1, 97, 168, 114, 14, 65, 60, 199, 182, 133, 130, 65, 175, + 95, 224, 125, 74, 157, 34, 99, 26, 135, 160, 188, 244, 114, 175, 211, 194, + 74, 97, 182, 244, 93, 3, 219, 223, 154, 204, 10, 132, 233, 165, 23, 204, + 187, 163, 179, 23, 72, 137, 22, 40, 123, 77, 216, 95, 44, 20, 55, 213, + 165, 125, 17, 237, 77, 140, 2, 146, 193, 104, 9, 83, 40, 126, 177, 137, + 53, 89, 59, 23, 49, 80, 240, 168, 70, 97, 250, 36, 161, 17, 228, 161, + 136, 213, 43, 118, 106, 198, 251, 68, 223, 34, 79, 123, 118, 91, 222, 236, + 73, 236, 175, 255, 248, 249, 96, 53, 245, 248, 238, 12, 106, 127, 183, 1, + 31, 193, 14, 126, 7, 19, 252, 102, 191, 74, 208, 115, 140, 76, 133, 179, + 82, 5, 83, 122, 154, 82, 37, 19, 171, 190, 177, 177, 233, 248, 175, 214, + 93, 17, 121, 167, 249, 165, 149, 191, 145, 188, 218, 99, 154, 55, 109, 202, + 12, 17, 56, 107, 124, 137, 156, 233, 85, 18, 237, 207, 9, 72, 10, 218, + 98, 58, 70, 254, 207, 179, 61, 201, 250, 163, 135, 215, 130, 182, 47, 93, + 123, 14, 251, 252, 34, 240, 172, 151, 111, 127, 19, 6, 165, 96, 254, 15, + 32, 153, 247, 91, 200, 78, 169, 160, 28, 70, 146, 251, 174, 49, 54, 98, + 93, 161, 19, 105, 195, 62, 196, 38, 84, 53, 122, 177, 158, 179, 113, 93, + 91, 102, 90, 119, 52, 120, 247, 208, 228, 233, 97, 240, 187, 205, 14, 194, + 35, 134, 229, 241, 16, 152, 130, 206, 63, 93, 110, 21, 52, 170, 67, 99, + 214, 121, 230, 201, 133, 173, 143, 225, 81, 184, 139, 105, 226, 58, 237, 106, + 16, 91, 163, 15, 4, 63, 94, 186, 80, 219, 85, 209, 183, 129, 122, 39, + 8, 140, 180, 203, 167, 223, 148, 74, 147, 29, 237, 108, 105, 143, 229, 254, + 104, 243, 111, 210, 11, 185, 158, 151, 90, 47, 43, 233, 91, 18, 119, 144, + 184, 63, 64, 3, 244, 225, 30, 134, 198, 210, 41, 103, 2, 31, 221, 74, + 26, 54, 18, 23, 242, 104, 39, 31, 167, 183, 209, 105, 192, 88, 219, 25, + 134, 228, 8, 222, 149, 25, 195, 141, 61, 33, 114, 213, 93, 6, 58, 12, + 191, 113, 216, 153, 39, 235, 173, 146, 34, 139, 210, 13, 59, 240, 88, 10, + 71, 72, 27, 225, 32, 70, 92, 182, 120, 151, 82, 246, 248, 93, 119, 13, + 199, 161, 48, 202, 84, 88, 226, 198, 249, 152, 165, 34, 183, 109, 9, 196, + 232, 168, 236, 241, 85, 100, 181, 81, 235, 85, 247, 85, 173, 57, 141, 145, + 116, 254, 146, 249, 161, 133, 245, 17, 117, 141, 208, 49, 245, 121, 181, 158, + 144, 197, 200, 63, 202, 119, 158, 107, 112, 56, 178, 227, 29, 87, 48, 151, + 228, 55, 194, 130, 52, 12, 35, 245, 171, 149, 90, 206, 151, 205, 184, 221, + 45, 57, 126, 64, 203, 244, 167, 172, 134, 141, 5, 145, 101, 29, 33, 133, + 90, 17, 64, 127, 152, 209, 78, 10, 131, 151, 157, 204, 231, 255, 164, 122, + 16, 78, 220, 245, 161, 229, 90, 203, 12, 205, 95, 8, 47, 51, 92, 23, + 118, 95, 211, 124, 116, 147, 74, 79, 10, 192, 217, 74, 80, 127, 17, 105, + 56, 248, 144, 72, 197, 159, 230, 19, 147, 31, 50, 239, 236, 92, 237, 131, + 159, 88, 99, 171, 76, 209, 41, 181, 194, 28, 3, 242, 137, 227, 20, 198, + 120, 6, 12, 97, 45, 210, 143, 177, 60, 83, 61, 135, 132, 187, 54, 61, + 82, 149, 193, 23, 45, 6, 95, 28, 167, 0, 67, 27, 17, 93, 241, 43, + 221, 109, 102, 179, 204, 80, 198, 60, 229, 38, 47, 100, 235, 50, 166, 193, + 79, 255, 71, 207, 116, 216, 201, 255, 134, 194, 201, 34, 169, 250, 28, 217, + 198, 176, 10, 203, 193, 197, 125, 80, 116, 149, 108, 224, 10, 195, 68, 228, + 218, 85, 146, 119, 67, 73, 118, 186, 171, 162, 86, 198, 176, 73, 41, 162, + 237, 196, 130, 32, 231, 70, 197, 139, 140, 182, 151, 221, 55, 95, 183, 58, + 43, 141, 160, 148, 193, 197, 162, 189, 62, 36, 226, 255, 214, 75, 166, 163, + 78, 30, 253, 52, 8, 190, 55, 241, 60, 187, 226, 34, 177, 102, 155, 56, + 165, 51, 183, 2, 181, 247, 125, 53, 36, 206, 73, 32, 19, 20, 204, 228, + 105, 254, 34, 201, 161, 175, 232, 223, 216, 103, 247, 13, 68, 49, 206, 172, + 122, 11, 17, 3, 55, 101, 94, 39, 18, 183, 214, 16, 149, 252, 137, 39, + 205, 84, 114, 80, 101, 246, 222, 173, 145, 229, 199, 73, 91, 219, 123, 235, + 45, 190, 39, 241, 146, 209, 124, 178, 151, 30, 19, 26, 112, 150, 192, 183, + 237, 124, 253, 165, 28, 130, 132, 161, 157, 140, 159, 163, 87, 181, 211, 166, + 233, 0, 180, 87, 125, 229, 173, 128, 90, 23, 38, 235, 143, 31, 117, 66, + 203, 76, 150, 249, 19, 23, 45, 184, 56, 249, 220, 114, 205, 1, 215, 169, + 205, 173, 58, 188, 128, 116, 122, 184, 48, 114, 95, 167, 3, 191, 136, 238, + 124, 245, 166, 82, 191, 16, 212, 149, 183, 166, 14, 212, 255, 67, 106, 50, + 159, 172, 211, 101, 207, 198, 242, 179, 40, 1, 73, 20, 64, 185, 29, 21, + 216, 246, 154, 104, 156, 214, 231, 192, 137, 220, 150, 215, 4, 80, 110, 164, + 185, 68, 114, 110, 234, 45, 143, 171, 196, 148, 151, 237, 16, 251, 68, 221, + 100, 18, 212, 110, 59, 147, 113, 217, 152, 28, 83, 198, 211, 231, 35, 39, + 198, 19, 163, 67, 40, 24, 124, 52, 138, 161, 254, 233, 90, 24, 214, 222, + 121, 189, 95, 180, 77, 147, 21, 187, 111, 9, 184, 75, 209, 250, 81, 110, + 34, 97, 198, 132, 182, 229, 192, 208, 67, 98, 124, 108, 141, 89, 37, 124, + 11, 5, 128, 76, 13, 220, 167, 201, 182, 151, 45, 235, 37, 142, 35, 192, + 28, 209, 254, 40, 15, 22, 183, 181, 138, 144, 72, 21, 48, 9, 133, 127, + 74, 187, 19, 170, 88, 209, 119, 194, 230, 243, 237, 156, 184, 156, 46, 118, + 58, 7, 139, 163, 157, 167, 65, 249, 102, 228, 201, 27, 255, 189, 54, 151, + 168, 108, 129, 113, 106, 245, 244, 158, 176, 247, 193, 161, 94, 248, 190, 38, + 208, 177, 246, 108, 158, 199, 56, 37, 141, 101, 102, 44, 109, 144, 23, 214, + 235, 251, 210, 184, 103, 145, 248, 118, 162, 139, 84, 61, 146, 29, 70, 170, + 80, 30, 145, 156, 202, 185, 222, 87, 247, 137, 153, 98, 166, 61, 173, 200, + 164, 40, 2, 137, 226, 66, 162, 24, 172, 46, 203, 80, 176, 156, 93, 26, + 48, 69, 130, 192, 129, 84, 70, 15, 25, 224, 175, 31, 161, 110, 61, 220, + 214, 220, 152, 22, 41, 51, 57, 114, 182, 139, 129, 159, 194, 169, 133, 246, + 37, 23, 79, 90, 88, 231, 6, 252, 101, 241, 250, 168, 71, 149, 252, 196, + 126, 2, 29, 177, 70, 218, 120, 203, 72, 243, 46, 45, 149, 57, 108, 37, + 198, 38, 177, 210, 32, 252, 227, 160, 77, 174, 211, 207, 212, 82, 139, 189, + 79, 198, 116, 165, 185, 49, 188, 43, 116, 230, 182, 34, 224, 138, 216, 93, + 93, 94, 175, 10, 217, 41, 209, 177, 36, 142, 205, 241, 34, 129, 8, 91, + 78, 210, 231, 166, 188, 18, 77, 139, 201, 203, 3, 154, 131, 8, 193, 207, + 255, 98, 166, 192, 215, 206, 236, 217, 9, 19, 78, 227, 105, 146, 56, 50, + 60, 114, 20, 239, 186, 119, 113, 183, 79, 186, 126, 223, 131, 30, 217, 249, + 82, 10, 188, 238, 161, 46, 174, 96, 6, 187, 251, 234, 62, 163, 213, 55, + 71, 253, 25, 193, 26, 176, 111, 20, 167, 220, 240, 78, 243, 42, 104, 194, + 0, 62, 53, 119, 199, 9, 202, 20, 164, 55, 155, 204, 107, 120, 180, 6, + 20, 114, 122, 130, 143, 124, 89, 130, 66, 140, 43, 183, 203, 216, 78, 86, + 178, 16, 226, 159, 192, 205, 105, 113, 138, 165, 108, 18, 214, 100, 154, 71, + 150, 46, 70, 178, 181, 68, 68, 160, 253, 18, 19, 220, 253, 207, 87, 105, + 32, 239, 229, 137, 155, 176, 139, 168, 248, 143, 86, 67, 224, 146, 17, 80, + 147, 87, 30, 168, 125, 169, 91, 59, 55, 169, 142, 226, 71, 181, 114, 40, + 231, 229, 155, 27, 31, 144, 166, 96, 9, 85, 90, 152, 25, 83, 113, 15, + 65, 106, 162, 151, 74, 7, 27, 188, 221, 150, 108, 96, 102, 233, 174, 208, + 9, 170, 159, 239, 67, 230, 187, 93, 141, 102, 218, 191, 48, 22, 53, 124, + 84, 96, 110, 43, 28, 126, 26, 32, 104, 104, 65, 99, 112, 207, 167, 54, + 175, 165, 152, 105, 234, 18, 138, 148, 101, 9, 87, 32, 155, 192, 7, 100, + 101, 72, 133, 203, 170, 248, 222, 190, 243, 0, 75, 100, 38, 52, 98, 125, + 66, 185, 104, 255, 8, 184, 116, 195, 32, 239, 213, 54, 28, 185, 96, 177, + 233, 30, 210, 25, 155, 28, 128, 53, 88, 101, 146, 68, 52, 60, 55, 183, + 171, 157, 207, 128, 53, 60, 22, 100, 53, 121, 124, 205, 163, 55, 82, 162, + 96, 99, 71, 184, 243, 169, 137, 77, 191, 16, 55, 59, 220, 197, 20, 4, + 61, 89, 4, 157, 96, 171, 145, 91, 145, 19, 36, 195, 42, 132, 152, 83, + 255, 137, 64, 37, 72, 190, 82, 29, 181, 41, 175, 144, 46, 229, 236, 217, + 105, 194, 7, 118, 19, 47, 151, 238, 222, 255, 183, 236, 181, 175, 135, 91, + 55, 163, 4, 156, 190, 18, 153, 21, 178, 51, 102, 36, 62, 253, 228, 12, + 102, 230, 138, 183, 182, 253, 54, 170, 251, 50, 107, 223, 180, 177, 74, 169, + 231, 208, 76, 47, 146, 158, 251, 181, 9, 219, 240, 169, 72, 250, 241, 125, + 86, 200, 125, 166, 137, 65, 115, 18, 68, 241, 124, 51, 128, 223, 113, 239, + 201, 221, 152, 21, 114, 127, 79, 101, 44, 48, 241, 21, 221, 91, 240, 214, + 166, 119, 140, 21, 143, 155, 172, 26, 207, 233, 0, 128, 118, 45, 22, 6, + 222, 75, 90, 99, 173, 214, 121, 53, 71, 183, 253, 19, 95, 71, 66, 16, + 41, 35, 195, 9, 93, 247, 42, 150, 49, 46, 229, 73, 220, 12, 230, 51, + 109, 147, 108, 124, 102, 83, 78, 75, 67, 141, 55, 246, 155, 195, 190, 56, + 116, 59, 185, 237, 104, 78, 66, 173, 165, 178, 32, 93, 14, 10, 46, 30, + 229, 108, 50, 52, 188, 2, 244, 142, 201, 8, 245, 53, 210, 132, 15, 184, + 82, 85, 156, 142, 35, 49, 39, 183, 58, 61, 96, 143, 60, 190, 41, 152, + 9, 183, 127, 90, 157, 109, 196, 76, 36, 177, 244, 173, 63, 233, 1, 16, + 110, 216, 203, 94, 245, 195, 71, 55, 161, 149, 230, 122, 159, 133, 143, 180, + 129, 6, 111, 56, 211, 30, 13, 142, 216, 122, 87, 69, 91, 233, 254, 4, + 232, 207, 157, 32, 113, 50, 227, 233, 158, 171, 38, 228, 191, 121, 56, 165, + 222, 22, 180, 217, 111, 104, 112, 134, 12, 22, 244, 44, 234, 34, 253, 217, + 212, 140, 93, 235, 36, 54, 4, 129, 32, 91, 197, 163, 24, 71, 133, 161, + 111, 114, 29, 19, 45, 100, 10, 207, 139, 158, 219, 206, 160, 248, 94, 12, + 241, 58, 118, 141, 115, 166, 177, 78, 173, 59, 85, 81, 97, 240, 154, 231, + 79, 200, 199, 195, 205, 98, 245, 129, 246, 217, 97, 209, 249, 194, 28, 179, + 49, 248, 14, 6, 128, 61, 178, 15, 190, 32, 251, 111, 225, 148, 0, 11, + 227, 246, 146, 46, 41, 231, 24, 80, 43, 174, 228, 166, 171, 206, 72, 142, + 253, 96, 242, 181, 31, 207, 95, 66, 88, 152, 165, 67, 7, 238, 23, 114, + 50, 224, 212, 241, 202, 224, 247, 70, 215, 162, 8, 237, 121, 169, 254, 191, + 30, 19, 72, 252, 3, 109, 5, 206, 105, 130, 69, 250, 250, 232, 135, 203, + 253, 77, 102, 203, 40, 72, 128, 223, 60, 59, 83, 103, 162, 117, 47, 200, + 65, 88, 43, 168, 168, 255, 46, 166, 86, 193, 231, 227, 92, 222, 186, 44, + 20, 166, 136, 123, 193, 88, 155, 166, 185, 73, 85, 124, 253, 80, 43, 176, + 173, 191, 2, 10, 50, 101, 143, 17, 129, 56, 191, 83, 103, 183, 143, 247, + 253, 161, 1, 76, 161, 76, 127, 194, 108, 88, 138, 152, 147, 164, 65, 147, + 61, 160, 192, 44, 56, 103, 144, 51, 153, 224, 38, 97, 173, 128, 34, 85, + 89, 143, 17, 239, 200, 47, 160, 2, 151, 249, 219, 208, 116, 71, 205, 72, + 210, 178, 205, 184, 207, 19, 37, 127, 183, 21, 229, 176, 91, 196, 203, 225, + 67, 189, 94, 214, 180, 203, 140, 186, 39, 250, 66, 3, 128, 35, 206, 43, + 67, 244, 207, 157, 165, 188, 201, 173, 43, 47, 210, 139, 254, 144, 218, 62, + 55, 6, 187, 32, 128, 206, 56, 74, 66, 42, 159, 171, 108, 56, 220, 246, + 127, 127, 32, 221, 190, 33, 91, 93, 88, 36, 51, 115, 93, 47, 203, 133, + 155, 166, 13, 124, 118, 56, 182, 202, 55, 224, 226, 36, 233, 9, 200, 217, + 249, 22, 252, 209, 179, 66, 32, 30, 129, 48, 186, 232, 66, 248, 197, 120, + 168, 191, 124, 16, 232, 117, 44, 125, 188, 157, 71, 35, 245, 219, 17, 111, + 41, 159, 96, 44, 233, 3, 105, 109, 199, 182, 42, 34, 87, 218, 48, 142, + 196, 99, 37, 89, 44, 173, 184, 160, 104, 203, 224, 230, 58, 60, 213, 132, + 9, 9, 253, 251, 72, 75, 235, 224, 20, 198, 208, 178, 42, 253, 126, 105, + 227, 171, 89, 93, 42, 222, 185, 232, 8, 248, 83, 78, 132, 37, 38, 173, + 67, 116, 185, 216, 47, 192, 196, 221, 172, 26, 5, 191, 41, 33, 114, 40, + 139, 22, 147, 173, 234, 41, 252, 118, 244, 73, 73, 237, 42, 6, 123, 228, + 213, 210, 202, 65, 195, 253, 112, 57, 202, 85, 247, 15, 160, 237, 138, 76, + 70, 94, 230, 163, 112, 217, 134, 78, 213, 55, 68, 198, 29, 195, 16, 138, + 162, 19, 34, 158, 144, 131, 64, 244, 80, 85, 63, 175, 47, 63, 233, 175, + 168, 190, 39, 4, 47, 200, 9, 161, 248, 198, 182, 166, 56, 23, 5, 121, + 188, 46, 90, 56, 216, 72, 203, 107, 212, 171, 110, 134, 255, 24, 243, 30, + 188, 55, 111, 8, 238, 198, 201, 180, 150, 230, 191, 248, 10, 82, 178, 247, + 114, 216, 83, 183, 24, 188, 131, 26, 246, 210, 42, 30, 111, 181, 215, 129, + 41, 21, 207, 15, 83, 86, 252, 169, 220, 246, 117, 114, 254, 143, 193, 60, + 123, 226, 202, 18, 77, 221, 135, 84, 180, 229, 79, 143, 241, 219, 217, 85, + 158, 63, 5, 245, 134, 63, 102, 68, 145, 100, 35, 13, 127, 241, 76, 211, + 204, 45, 125, 175, 128, 142, 244, 189, 203, 138, 63, 249, 2, 174, 167, 171, + 32, 131, 12, 250, 248, 198, 245, 3, 98, 4, 111, 244, 226, 122, 136, 58, + 189, 234, 244, 106, 117, 92, 97, 191, 247, 95, 114, 20, 151, 51, 67, 174, + 236, 109, 252, 215, 107, 183, 174, 254, 59, 22, 158, 203, 152, 194, 135, 200, + 61, 193, 249, 199, 24, 167, 119, 223, 205, 135, 112, 51, 118, 120, 253, 75, + 61, 101, 172, 213, 36, 226, 135, 54, 229, 214, 151, 9, 2, 197, 84, 22, + 207, 55, 182, 191, 53, 243, 63, 53, 13, 93, 121, 44, 174, 237, 192, 138, + 116, 208, 200, 134, 94, 34, 122, 110, 157, 231, 169, 177, 180, 203, 167, 125, + 73, 44, 57, 104, 204, 174, 36, 172, 47, 21, 36, 220, 92, 62, 191, 77, + 113, 5, 32, 8, 115, 61, 235, 237, 27, 76, 69, 187, 117, 72, 26, 49, + 217, 249, 130, 134, 139, 27, 229, 183, 146, 80, 3, 154, 25, 26, 52, 175, + 157, 1, 91, 126, 165, 6, 168, 134, 60, 32, 227, 68, 161, 126, 207, 247, + 160, 103, 105, 156, 129, 211, 220, 155, 222, 60, 184, 255, 149, 9, 116, 201, + 151, 42, 126, 0, 36, 167, 178, 40, 160, 5, 115, 82, 176, 207, 38, 10, + 213, 132, 57, 255, 138, 4, 204, 32, 33, 128, 174, 99, 94, 161, 237, 0, + 230, 209, 198, 89, 167, 80, 193, 116, 195, 111, 204, 241, 169, 46, 117, 108, + 244, 247, 12, 216, 106, 50, 242, 209, 61, 42, 214, 33, 25, 38, 138, 217, + 225, 105, 76, 244, 126, 252, 253, 57, 238, 107, 166, 158, 250, 132, 105, 91, + 184, 209, 217, 5, 202, 84, 254, 51, 233, 58, 2, 141, 130, 47, 97, 125, + 244, 95, 177, 68, 9, 213, 115, 118, 215, 70, 9, 64, 113, 139, 19, 165, + 231, 204, 191, 129, 15, 235, 143, 225, 241, 75, 168, 227, 126, 58, 201, 98, + 16, 227, 27, 148, 166, 1, 34, 110, 84, 120, 11, 181, 150, 111, 167, 184, + 49, 244, 231, 192, 44, 59, 41, 122, 58, 12, 185, 180, 54, 122, 106, 201, + 2, 65, 118, 129, 149, 139, 31, 201, 205, 90, 96, 76, 23, 43, 218, 15, + 233, 202, 103, 84, 18, 122, 25, 218, 38, 252, 222, 104, 172, 96, 30, 57, + 205, 130, 106, 183, 189, 230, 67, 63, 162, 142, 46, 199, 45, 244, 3, 26, + 208, 119, 15, 16, 29, 196, 178, 90, 41, 94, 193, 64, 51, 205, 136, 157 +}; + diff --git a/baseline/source/rijndael_dec/rijndael_dec.c b/baseline/source/rijndael_dec/rijndael_dec.c new file mode 100644 index 0000000..4082eff --- /dev/null +++ b/baseline/source/rijndael_dec/rijndael_dec.c @@ -0,0 +1,195 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: rijndael_enc + + Author: Dr Brian Gladman + + Function: rijndael_dec is an implementation of the AES decryption + algorithm (Rijndael). + + Source: security section of MiBench + + Changes: Add computation of a checksum, refactoring + + License: see below + +*/ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +#include "../extra.h" +#include "aes.h" +#include "rijndael_dec_libc.h" + +/* + Global variable definitions +*/ +unsigned char rijndael_dec_key[32]; +int rijndael_dec_key_len; + +extern unsigned char rijndael_dec_data[]; +struct rijndael_dec_FILE rijndael_dec_fin; + +int rijndael_dec_checksum = 0; + +/* + Forward declaration of functions +*/ +void rijndael_dec_init( void ); +int rijndael_dec_return( void ); +void rijndael_dec_fillrand( unsigned char *buf, int len ); +void rijndael_dec_decfile( struct rijndael_dec_FILE *fin, struct aes *ctx ); +void rijndael_dec_main( void ); + +void rijndael_dec_init( void ) +{ + /* create a pseudo-file for the input*/ + rijndael_dec_fin.data = rijndael_dec_data; + rijndael_dec_fin.size = 32768; + rijndael_dec_fin.cur_pos = 0; + + unsigned i; + volatile int x = 0; + rijndael_dec_fin.size ^= x; + _Pragma( "loopbound min 32768 max 32768" ) + for ( i = 0; i < rijndael_dec_fin.size; i++ ) + rijndael_dec_fin.data[i] ^= x; + + /* this is a pointer to the hexadecimal key digits */ + const volatile char *cp = + "1234567890abcdeffedcba09876543211234567890abcdeffedcba0987654321"; + char ch; + int by = 0; + + i = 0; /* this is a count for the input digits processed */ + _Pragma( "loopbound min 64 max 64" ) + while ( i < 64 && *cp ) { /* the maximum key length is 32 bytes and */ + /* hence at most 64 hexadecimal digits */ + ch = rijndael_dec_toupper( *cp++ ); /* process a hexadecimal digit */ + if ( ch >= '0' && ch <= '9' ) + by = ( by << 4 ) + ch - '0'; + else + if ( ch >= 'A' && ch <= 'F' ) + by = ( by << 4 ) + ch - 'A' + 10; + else { /* error if not hexadecimal */ + rijndael_dec_checksum = -2; + return; + } + + /* store a key byte for each pair of hexadecimal digits */ + if ( i++ & 1 ) + rijndael_dec_key[i / 2 - 1] = by & 0xff; + } + + if ( *cp ) { + rijndael_dec_checksum = -3; + return; + } else + if ( i < 32 || ( i & 15 ) ) { + rijndael_dec_checksum = -4; + return; + } + + rijndael_dec_key_len = i / 2; +} + +int rijndael_dec_return( void ) +{ + return ( ( rijndael_dec_checksum == ( int )262180 ) ? 0 : -1 ); +} + +void rijndael_dec_decfile( struct rijndael_dec_FILE *fin, struct aes *ctx ) +{ + unsigned char inbuf1[16], inbuf2[16], outbuf[16], *bp1, *bp2, *tp; + int i; + + + rijndael_dec_fread( inbuf1, 1, 16, fin ); + + i = rijndael_dec_fread( inbuf2, 1, 16, + fin ); /* read 1st encrypted file block */ + + if ( i && i != 16 ) { + rijndael_dec_checksum = -10; + return; + } + + rijndael_dec_decrypt( inbuf2, outbuf, + ctx ); /* decrypt it */ + + rijndael_dec_checksum += outbuf[15]; + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor with previous input */ + outbuf[i] ^= inbuf1[i]; + + bp1 = inbuf1; /* set up pointers to two input buffers */ + bp2 = inbuf2; + + /* TODO: this is necessarily an input-dependent loop bound */ + _Pragma( "loopbound min 19491 max 91491" ) + while ( 1 ) { + i = rijndael_dec_fread( bp1, 1, 16, fin ); /* read next encrypted block */ + /* to first input buffer */ + if ( i != 16 ) /* no more bytes in input - the decrypted */ + break; /* partial final buffer needs to be output */ + + /* if a block has been read the previous block must have been */ + /* full lnegth so we can now write it out */ + + rijndael_dec_decrypt( bp1, outbuf, ctx ); /* decrypt the new input block and */ + + rijndael_dec_checksum += outbuf[15]; + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor it with previous input block */ + outbuf[i] ^= bp2[i]; + + /* swap buffer pointers */ + tp = bp1, bp1 = bp2, bp2 = tp; + } +} + +void _Pragma( "entrypoint" ) rijndael_dec_main( void ) +{ + struct aes ctx[1]; + + /* decryption in Cipher Block Chaining mode */ + rijndael_dec_set_key( rijndael_dec_key, rijndael_dec_key_len, dec, ctx ); + rijndael_dec_decfile( &rijndael_dec_fin, ctx ); +} + +int main(int argc, char** argv) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= 'a' ) && ( c <= 'z' ) ) + return c - 'a' + 'A'; + return c; +} + +unsigned long rijndael_dec_fread( void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_read = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 10 max 16" ) + while ( i < stream->cur_pos + number_of_chars_to_read ) + ( ( unsigned char * )ptr )[i2++] = stream->data[i++]; + stream->cur_pos += number_of_chars_to_read; + return number_of_chars_to_read; +} + +unsigned long rijndael_dec_fwrite( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_write = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 0 max 0" ) + while ( i < stream->cur_pos + number_of_chars_to_write ) + stream->data[i++] = ( ( unsigned char * )ptr )[i2++]; + stream->cur_pos += number_of_chars_to_write; + return number_of_chars_to_write; +} + +int rijndael_dec_fseek( struct rijndael_dec_FILE *stream, long int offset, + Origin origin ) +{ + if ( origin == RIJNDAEL_DEC_SEEK_SET ) { + stream->cur_pos = offset; + return 0; + } else + if ( origin == RIJNDAEL_DEC_SEEK_CUR ) { + stream->cur_pos += offset; + return 0; + } else + if ( origin == RIJNDAEL_DEC_SEEK_END ) { + stream->cur_pos = stream->size + offset; + return 0; + } + return -1; +} + +int rijndael_dec_fgetpos( struct rijndael_dec_FILE *stream, + unsigned *position ) +{ + *position = stream->cur_pos; + return 0; +} + +int rijndael_dec_feof( struct rijndael_dec_FILE *stream ) +{ + return stream->cur_pos == stream->size ? 1 : 0; +} diff --git a/baseline/source/rijndael_dec/rijndael_dec_libc.h b/baseline/source/rijndael_dec/rijndael_dec_libc.h new file mode 100644 index 0000000..eb7b8d6 --- /dev/null +++ b/baseline/source/rijndael_dec/rijndael_dec_libc.h @@ -0,0 +1,24 @@ +#ifndef RIJNDAEL_DEC_LIBC_H +#define RIJNDAEL_DEC_LIBC_H + +int rijndael_dec_toupper ( int c ); + +enum _Origin_ { RIJNDAEL_DEC_SEEK_SET, RIJNDAEL_DEC_SEEK_CUR, RIJNDAEL_DEC_SEEK_END }; +typedef enum _Origin_ Origin; +struct rijndael_dec_FILE { + unsigned char *data; + unsigned long size; + unsigned cur_pos; +}; + +unsigned long rijndael_dec_fread ( void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ); +unsigned long rijndael_dec_fwrite ( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_dec_FILE *stream ); +int rijndael_dec_fseek ( struct rijndael_dec_FILE *stream, long int offset, + Origin origin ); +int rijndael_dec_fgetpos( struct rijndael_dec_FILE *stream, + unsigned *position ); +int rijndael_dec_feof ( struct rijndael_dec_FILE *stream ); + +#endif // RIJNDAEL_DEC_LIBC_H diff --git a/baseline/source/rijndael_enc/ChangeLog.txt b/baseline/source/rijndael_enc/ChangeLog.txt new file mode 100644 index 0000000..6ea9ed4 --- /dev/null +++ b/baseline/source/rijndael_enc/ChangeLog.txt @@ -0,0 +1,98 @@ +File: rijndael_encoder.c +Source: security section of MiBench + +2016-02-26: +- Remove commented-out code +- Prefix functions with "rijndael_enc" +- Compute a checksum and return it from main +- Change return type of rijndael_enc_encfile to void +- Move functionality from function main into functions + rijndael_enc_init, rijndael_enc_main, and rijndael_enc_return +- Reordered functions in source code: initialization- and + return-value-related functions first, followed by algorithm core + functions, followed by main functions +- Added function prototypes +- Applied code formatting with astyle as in the example +- Added general TACLeBench header to beginning of source code +- Rename to rijndael_enc.c + +2016-03-15: +- Return 0 if checksum is as expected, -1 otherwise +- Add entrypoint pragma +- Make inputs volatile (or touch them with a volatile) to rule out + optimizations + +2016-04-20: +- Cast "expected" return value to int for comparison +- Make loop counter in rijndael_enc_init unsigned + +Files: aes.c, aes.h, aestab.h +Source: security section of MiBench + +2016-02-26: +- Remove unused defines UNROLL, PARTIAL_UNROLL +- Remove defines FIXED_TABLES, FF_TABLES, ARRAYS, FOUR_TABLES, + FOUR_LR_TABLES, FOUR_IM_TABLES +- Remove (undefined) define ONE_TABLE, ONE_LR_TABLE , ONE_IM_TABLE +- Assume BLOCK_SIZE is always 16 +- Remove unused define "unused" +- Remove INTERNAL_BYTE_ORDER, EXTERNAL_BYTE_ORDER, AES_BIG_ENDIAN, + AES_LITTLE_ENDIAN (assume internal == external == little endian) +- Remove defines AES_DLL and AES_IN_CPP +- Remove "#if defined(__cplusplus)" +- Replace macros c_name and cf_dec with their definition +- Remove some stale comments +- Remove defines no_table and one_table +- Remove prototypes for unusedfunctions decrypt and set_blk +- Prefix all functions and global variables with "rijndael_enc" +- Break lines in overly long macros +- Protect macros +- Applied code formatting with astyle as in the example + +2016-04-20: +- Remove unused macros s, ff_poly, ff_hi, m1, m2, m3, FFmulX, + fwd_mcol, fwd_var, inv_var, si, so, fwd_rnd, inv_rnd, fwd_lrnd, + inv_lrnd, locals, l_copy, state_in, state_out, round, i_table, + li_table +- Remove unused arrays rijndael_enc_s_box, rijndael_enc_inv_s_box, + rijndael_enc_it_tab, rijndael_enc_il_tab + +2016-06-14: +- Added cast to make C++ compiler happy + +Files: glibc_common.h, my_file.h +Source: security section of MiBench + +2016-02-26: +- Merge into file rijndael_enc_libc.h + +File: rijndael_enc_libc.h + +2016-02-26: +- Replace size_x with unsigned long +- Remove defines LITTLE_ENDIAN and NULL +- Prefix all functions with "rijndael_enc" (instead of "my_") +- Prefix definitions that clash with the standard library with + "rijndael_enc" (instead of "my_") +- Applied code formatting with astyle as in the example + +Files: glibc_common.c, my_file.c +Source: security section of MiBench + +2016-02-26: +- Merge into file rijndael_enc_libc.c + +File: rijndael_enc_libc.c + +2016-02-26: +- Replace size_x with unsigned long +- Prefix all functions with "rijndael_enc" (instead of "my_") +- Prefix definitions that clash with the standard library with + "rijndael_enc" (instead of "my_") +- Applied code formatting with astyle as in the example + +File: input_small.c +Source: security section of MiBench + +2016-02-26: +- Break long lines diff --git a/baseline/source/rijndael_enc/aes.c b/baseline/source/rijndael_enc/aes.c new file mode 100644 index 0000000..c1282a7 --- /dev/null +++ b/baseline/source/rijndael_enc/aes.c @@ -0,0 +1,406 @@ +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of 128, + bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. +*/ + +#include "aes.h" + +#include "aestab.h" + +#define four_tables(x,tab,vf,rf,c) ( tab[0][bval(vf(x,0,c),rf(0,c))] ^ \ + tab[1][bval(vf(x,1,c),rf(1,c))] ^ \ + tab[2][bval(vf(x,2,c),rf(2,c))] ^ \ + tab[3][bval(vf(x,3,c),rf(3,c))] ) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((r-c)&3) + +#define ls_box(x,c) four_tables(x,rijndael_enc_fl_tab,vf1,rf2,c) + +#define inv_mcol(x) four_tables(x,rijndael_enc_im_tab,vf1,rf1,0) + +/* + Subroutine to set the block size (if variable) in bytes, legal + values being 16, 24 and 32. +*/ + +#define nc (Ncol) + +/* + Initialise the key schedule from the user supplied key. The key + length is now specified in bytes - 16, 24 or 32 as appropriate. + This corresponds to bit lengths of 128, 192 and 256 bits, and + to Nk values of 4, 6 and 8 respectively. +*/ + +#define mx(t,f) (*t++ = inv_mcol(*f),f++) +#define cp(t,f) *t++ = *f++ + +#define cpy(d,s) do { cp(d,s); cp(d,s); cp(d,s); cp(d,s); } while (0) +#define mix(d,s) do { mx(d,s); mx(d,s); mx(d,s); mx(d,s); } while (0) + +aes_ret rijndael_enc_set_key( byte in_key[], const word n_bytes, + const enum aes_key f, struct aes *cx ) +{ + word *kf, *kt, rci; + + if ( ( n_bytes & 7 ) || n_bytes < 16 || n_bytes > 32 || ( !( f & 1 ) && + !( f & 2 ) ) ) + return ( n_bytes ? cx->mode &= ~0x03, aes_bad : ( aes_ret )( cx->Nkey << 2 ) ); + + cx->mode = ( cx->mode & ~0x03 ) | ( ( byte )f & 0x03 ); + cx->Nkey = n_bytes >> 2; + cx->Nrnd = Nr( cx->Nkey, ( word )nc ); + + cx->e_key[0] = word_in( in_key ); + cx->e_key[1] = word_in( in_key + 4 ); + cx->e_key[2] = word_in( in_key + 8 ); + cx->e_key[3] = word_in( in_key + 12 ); + + kf = cx->e_key; + kt = kf + nc * ( cx->Nrnd + 1 ) - cx->Nkey; + rci = 0; + + switch ( cx->Nkey ) { + case 4: + _Pragma( "loopbound min 0 max 0" ) + do { + kf[4] = kf[0] ^ ls_box( kf[3], 3 ) ^ rijndael_enc_rcon_tab[rci++]; + kf[5] = kf[1] ^ kf[4]; + kf[6] = kf[2] ^ kf[5]; + kf[7] = kf[3] ^ kf[6]; + kf += 4; + } while ( kf < kt ); + break; + + case 6: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + _Pragma( "loopbound min 0 max 0" ) + do { + kf[ 6] = kf[0] ^ ls_box( kf[5], 3 ) ^ rijndael_enc_rcon_tab[rci++]; + kf[ 7] = kf[1] ^ kf[ 6]; + kf[ 8] = kf[2] ^ kf[ 7]; + kf[ 9] = kf[3] ^ kf[ 8]; + kf[10] = kf[4] ^ kf[ 9]; + kf[11] = kf[5] ^ kf[10]; + kf += 6; + } while ( kf < kt ); + break; + + case 8: + cx->e_key[4] = word_in( in_key + 16 ); + cx->e_key[5] = word_in( in_key + 20 ); + cx->e_key[6] = word_in( in_key + 24 ); + cx->e_key[7] = word_in( in_key + 28 ); + _Pragma( "loopbound min 7 max 7" ) + do { + kf[ 8] = kf[0] ^ ls_box( kf[7], 3 ) ^ rijndael_enc_rcon_tab[rci++]; + kf[ 9] = kf[1] ^ kf[ 8]; + kf[10] = kf[2] ^ kf[ 9]; + kf[11] = kf[3] ^ kf[10]; + kf[12] = kf[4] ^ ls_box( kf[11], 0 ); + kf[13] = kf[5] ^ kf[12]; + kf[14] = kf[6] ^ kf[13]; + kf[15] = kf[7] ^ kf[14]; + kf += 8; + } while ( kf < kt ); + break; + } + + if ( ( cx->mode & 3 ) != enc ) { + word i; + + kt = cx->d_key + nc * cx->Nrnd; + kf = cx->e_key; + + cpy( kt, kf ); + kt -= 2 * nc; + + _Pragma( "loopbound min 0 max 0" ) + for ( i = 1; i < cx->Nrnd; ++i ) { + mix( kt, kf ); + kt -= 2 * nc; + } + + cpy( kt, kf ); + } + + return aes_good; +} + +short rijndael_enc_encrypt( unsigned char in_blk[], unsigned char out_blk[], + const struct aes *cx ) +{ + const unsigned long *kp = cx->e_key; + if ( !( cx->mode & 1 ) ) + return 0; + unsigned long b0[4]; + b0[0] = *( unsigned long * )in_blk ^ kp[0]; + b0[1] = *( unsigned long * )( in_blk + 4 )^kp[1]; + b0[2] = *( unsigned long * )( in_blk + 8 )^kp[2]; + b0[3] = *( unsigned long * )( in_blk + 12 )^kp[3]; + kp += 4; + unsigned long b1[4]; + switch ( cx->Nrnd ) { + case 14: + b1[0] = kp[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + kp += 8; + case 12: + b1[0] = kp[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + kp += 8; + case 10: + b1[0] = kp[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = kp[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = kp[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = kp[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 4 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 4 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 4 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 4 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 8 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 8 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 8 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 8 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 12 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 12 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 12 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 12 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 16 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 16 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 16 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 16 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 20 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 20 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 20 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 20 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 24 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 24 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 24 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 24 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 28 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 28 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 28 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 28 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + b1[0] = ( kp + 32 )[0] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[0] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[1] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[2] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[3] >> 24 ) )] ); + b1[1] = ( kp + 32 )[1] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[1] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[2] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[3] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[0] >> 24 ) )] ); + b1[2] = ( kp + 32 )[2] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[2] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[3] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[0] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[1] >> 24 ) )] ); + b1[3] = ( kp + 32 )[3] ^ ( rijndael_enc_ft_tab[0][( ( unsigned char )b0[3] )] ^ + rijndael_enc_ft_tab[1][( ( unsigned char )( b0[0] >> 8 ) )] ^ + rijndael_enc_ft_tab[2][( ( unsigned char )( b0[1] >> 16 ) )] ^ + rijndael_enc_ft_tab[3][( ( unsigned char )( b0[2] >> 24 ) )] ); + b0[0] = ( kp + 36 )[0] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[0] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[1] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[2] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[3] >> 24 ) )] ); + b0[1] = ( kp + 36 )[1] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[1] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[2] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[3] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[0] >> 24 ) )] ); + b0[2] = ( kp + 36 )[2] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[2] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[3] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[0] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[1] >> 24 ) )] ); + b0[3] = ( kp + 36 )[3] ^ ( rijndael_enc_fl_tab[0][( ( unsigned char )b1[3] )] ^ + rijndael_enc_fl_tab[1][( ( unsigned char )( b1[0] >> 8 ) )] ^ + rijndael_enc_fl_tab[2][( ( unsigned char )( b1[1] >> 16 ) )] ^ + rijndael_enc_fl_tab[3][( ( unsigned char )( b1[2] >> 24 ) )] ); + } + *( unsigned long * )out_blk = ( b0[0] ); + *( unsigned long * )( out_blk + 4 ) = ( b0[1] ); + *( unsigned long * )( out_blk + 8 ) = ( b0[2] ); + *( unsigned long * )( out_blk + 12 ) = ( b0[3] ); + return aes_good; +} + diff --git a/baseline/source/rijndael_enc/aes.h b/baseline/source/rijndael_enc/aes.h new file mode 100644 index 0000000..908f95f --- /dev/null +++ b/baseline/source/rijndael_enc/aes.h @@ -0,0 +1,165 @@ +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- + + 1. FUNCTION + + The AES algorithm Rijndael implemented for block and key sizes of + 128 bits (16 bytes) by Brian Gladman. + + This is an implementation of the AES encryption algorithm (Rijndael) + designed by Joan Daemen and Vincent Rijmen. + + 2. THE CIPHER INTERFACE + + byte (an unsigned 8-bit type) + word (an unsigned 32-bit type) + aes_ret: (a signed 16 bit type for function return values) + aes_good (value != 0, a good return) + aes_bad (value == 0, an error return) + enum aes_key: (encryption direction) + enc (set key for encryption) + dec (set key for decryption) + both (set key for both) + class or struct aes (structure for context) + + C subroutine calls: + + aes_ret set_blk(const word block_length, aes *cx) (variable block size) + aes_ret set_key(const byte key[], const word key_length, + const enum aes_key direction, aes *cx) + aes_ret encrypt(const byte input_blk[], byte output_blk[], const aes *cx) + aes_ret decrypt(const byte input_blk[], byte output_blk[], const aes *cx) + + IMPORTANT NOTE: If you are using this C interface and your compiler does + not set the memory used for objects to zero before use, you will need to + ensure that cx.mode is set to zero before using the C subroutine calls. + + The block length inputs to set_block and set_key are in numbers of + BYTES, not bits. The calls to subroutines must be made in the above + order but multiple calls can be made without repeating earlier calls + if their parameters have not changed. If the cipher block length is + variable but set_blk has not been called before cipher operations a + value of 16 is assumed (that is, the AES block size). In contrast to + earlier versions the block and key length parameters are now checked + for correctness and the encryption and decryption routines check to + ensure that an appropriate key has been set before they are called. + +*/ + +#ifndef _AES_H +#define _AES_H + +/* The only supported block size for the benchmark is 16 */ +#define BLOCK_SIZE 16 + +/* + The number of key schedule words for different block and key lengths + (allowing for the method of computation which requires the length to + be a multiple of the key length): + + Key Schedule key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 44 60 54 56 64 + length 20 | 60 60 66 70 80 + (bytes) 24 | 80 80 78 84 96 + 28 | 100 100 102 98 112 + 32 | 120 120 120 126 120 + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + The following values assume that the key length will be variable and may + be of maximum length (32 bytes). + + Nk = number_of_key_bytes / 4 + Nc = number_of_columns_in_state / 4 + Nr = number of encryption/decryption rounds + Rc = number of elements in rcon table + Ks = number of 32-bit words in key schedule +*/ + +#define Nr(Nk,Nc) ((Nk > Nc ? Nk : Nc) + 6) +#define Rc(Nk,Nc) ((Nb * (Nr(Nk,Nc) + 1) - 1) / Nk) +#define Ks(Nk,Nc) (Nk * (Rc(Nk,Nc) + 1)) + +#define RC_LENGTH 5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11) +#define KS_LENGTH 4 * BLOCK_SIZE + +/* End of configuration options, but see also aes.c */ + +typedef unsigned char byte; /* must be an 8-bit storage unit */ +typedef unsigned long word; /* must be a 32-bit storage unit */ +typedef short aes_ret; /* function return value */ + +#define aes_bad 0 +#define aes_good 1 + +/* + upr(x,n): rotates bytes within words by n positions, moving bytes + to higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word +*/ + +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) +#define ups(x,n) ((x) << 8 * (n)) +#define bval(x,n) ((byte)((x) >> 8 * (n))) +#define byte_swap(x) (upr(x,1) & 0x00ff00ff | upr(x,3) & 0xff00ff00) +#define bytes2word(b0, b1, b2, b3) ((word)(b3) << 24 | (word)(b2) << 16 | \ + (word)(b1) << 8 | (b0)) + +#define word_in(x) *(word*)(x) +#define word_out(x,v) *(word*)(x) = (v) + +enum aes_const { Nrow = 4, /* the number of rows in the cipher state */ + Mcol = 8, /* maximum number of columns in the state */ + Ncol = BLOCK_SIZE / 4, + Shr0 = 0, /* the cyclic shift values for rows 0, 1, 2 & 3 */ + Shr1 = 1, + Shr2 = BLOCK_SIZE == 32 ? 3 : 2, + Shr3 = BLOCK_SIZE == 32 ? 4 : 3 + }; + +enum aes_key { enc = 1, /* set if encryption is needed */ + dec = 2, /* set if decryption is needed */ + both = 3 /* set if both are needed */ + }; + +struct aes { + word Nkey; /* the number of words in the key input block */ + word Nrnd; /* the number of cipher rounds */ + word e_key[KS_LENGTH]; /* the encryption key schedule */ + word d_key[KS_LENGTH]; /* the decryption key schedule */ + byte mode; /* encrypt, decrypt or both */ +}; + +aes_ret rijndael_enc_set_key( byte key[], const word n_bytes, + const enum aes_key f, struct aes *cx ); +aes_ret rijndael_enc_encrypt( byte in_blk[], byte out_blk[], + const struct aes *cx ); + +#endif diff --git a/baseline/source/rijndael_enc/aestab.h b/baseline/source/rijndael_enc/aestab.h new file mode 100644 index 0000000..9d347bc --- /dev/null +++ b/baseline/source/rijndael_enc/aestab.h @@ -0,0 +1,261 @@ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +/* + Used to ensure table is generated in the right format + depending on the internal byte order required. +*/ + +#define w0(p) 0x000000##p + +/* + Number of elements required in this table for different + block and key lengths is: + + Rcon Table key length (bytes) + Length 16 20 24 28 32 + --------------------- + block 16 | 10 9 8 7 7 + length 20 | 14 11 10 9 9 + (bytes) 24 | 19 15 12 11 11 + 28 | 24 19 16 13 13 + 32 | 29 23 19 17 14 + + this table can be a table of bytes if the key schedule + code is adjusted accordingly +*/ + +const word rijndael_enc_rcon_tab[29] = { + w0( 01 ), w0( 02 ), w0( 04 ), w0( 08 ), + w0( 10 ), w0( 20 ), w0( 40 ), w0( 80 ), + w0( 1b ), w0( 36 ), w0( 6c ), w0( d8 ), + w0( ab ), w0( 4d ), w0( 9a ), w0( 2f ), + w0( 5e ), w0( bc ), w0( 63 ), w0( c6 ), + w0( 97 ), w0( 35 ), w0( 6a ), w0( d4 ), + w0( b3 ), w0( 7d ), w0( fa ), w0( ef ), + w0( c5 ) +}; + +#undef w0 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +#define r0(p,q,r,s) 0x##p##q##r##s +#define r1(p,q,r,s) 0x##q##r##s##p +#define r2(p,q,r,s) 0x##r##s##p##q +#define r3(p,q,r,s) 0x##s##p##q##r +#define w0(p) 0x000000##p +#define w1(p) 0x0000##p##00 +#define w2(p) 0x00##p##0000 +#define w3(p) 0x##p##000000 + +/* + used to ensure table is generated in the right format + depending on the internal byte order required +*/ + +/* data for forward tables (other than last round) */ + +#define f_table \ + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6), \ + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91), \ + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56), \ + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec), \ + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa), \ + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb), \ + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45), \ + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b), \ + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c), \ + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83), \ + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9), \ + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a), \ + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d), \ + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f), \ + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df), \ + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea), \ + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34), \ + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b), \ + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d), \ + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13), \ + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1), \ + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6), \ + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72), \ + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85), \ + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed), \ + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11), \ + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe), \ + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b), \ + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05), \ + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1), \ + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42), \ + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf), \ + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3), \ + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e), \ + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a), \ + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6), \ + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3), \ + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b), \ + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28), \ + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad), \ + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14), \ + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8), \ + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4), \ + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2), \ + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da), \ + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49), \ + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf), \ + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10), \ + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c), \ + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97), \ + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e), \ + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f), \ + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc), \ + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c), \ + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69), \ + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27), \ + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22), \ + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33), \ + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9), \ + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5), \ + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a), \ + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0), \ + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e), \ + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) + +/* generate the required tables in the desired endian format */ + +#undef r +#define r r0 + +const word rijndael_enc_ft_tab[4][256] = { + { f_table }, +#undef r +#define r r1 + { f_table }, +#undef r +#define r r2 + { f_table }, +#undef r +#define r r3 + { f_table } +}; + +/* generate the required tables in the desired endian format */ + +#undef r +#define r(p,q,r,s) w0(q) +const word rijndael_enc_fl_tab[4][256] = { + { f_table }, +#undef r +#define r(p,q,r,s) w1(q) + { f_table }, +#undef r +#define r(p,q,r,s) w2(q) + { f_table }, +#undef r +#define r(p,q,r,s) w3(q) + { f_table } +}; + +#define m_table \ + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12), \ + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a), \ + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62), \ + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a), \ + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2), \ + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca), \ + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82), \ + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba), \ + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9), \ + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1), \ + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9), \ + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81), \ + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29), \ + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11), \ + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59), \ + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61), \ + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf), \ + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87), \ + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf), \ + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7), \ + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f), \ + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67), \ + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f), \ + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17), \ + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64), \ + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c), \ + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14), \ + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c), \ + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84), \ + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc), \ + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4), \ + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc), \ + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53), \ + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b), \ + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23), \ + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b), \ + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3), \ + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b), \ + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3), \ + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb), \ + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88), \ + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0), \ + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8), \ + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0), \ + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68), \ + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50), \ + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18), \ + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20), \ + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe), \ + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6), \ + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e), \ + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6), \ + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e), \ + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26), \ + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e), \ + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56), \ + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25), \ + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d), \ + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55), \ + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d), \ + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5), \ + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd), \ + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5), \ + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d) + +#undef r +#define r r0 + +const word rijndael_enc_im_tab[4][256] = { + { m_table }, +#undef r +#define r r1 + { m_table }, +#undef r +#define r r2 + { m_table }, +#undef r +#define r r3 + { m_table } +}; diff --git a/baseline/source/rijndael_enc/input_small.c b/baseline/source/rijndael_enc/input_small.c new file mode 100644 index 0000000..b3eee55 --- /dev/null +++ b/baseline/source/rijndael_enc/input_small.c @@ -0,0 +1,1963 @@ +unsigned char rijndael_enc_data[] = { + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','t','s','C','o', + 'm','m','e','n','c','e','m','e','n','t','A','d','d','r','e','s', + 's','a','t','M','I','T','L','a','d','i','e','s','a','n','d','g', + 'e','n','t','l','e','m','e','n','o','f','t','h','e','c','l','a', + 's','s','o','f','9','7','W','e','a','r','s','u','n','s','c','r', + 'e','e','n','I','f','I','c','o','u','l','d','o','f','f','e','r', + 'y','o','u','o','n','l','y','o','n','e','t','i','p','f','o','r', + 't','h','e','f','u','t','u','r','e','s','u','n','s','c','r','e', + 'e','n','w','o','u','l','d','b','e','i','t','T','h','e','l','o', + 'n','g','t','e','r','m','b','e','n','e','f','i','t','s','o','f', + 's','u','n','s','c','r','e','e','n','h','a','v','e','b','e','e', + 'n','p','r','o','v','e','d','b','y','s','c','i','e','n','t','i', + 's','t','s','w','h','e','r','e','a','s','t','h','e','r','e','s', + 't','o','f','m','y','a','d','v','i','c','e','h','a','s','n','o', + 'b','a','s','i','s','m','o','r','e','r','e','l','i','a','b','l', + 'e','t','h','a','n','m','y','o','w','n','m','e','a','n','d','e', + 'r','i','n','g','e','x','p','e','r','i','e','n','c','e','I','w', + 'i','l','l','d','i','s','p','e','n','s','e','t','h','i','s','a', + 'd','v','i','c','e','n','o','w','E','n','j','o','y','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','O','h','n','e','v','e','r', + 'm','i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n', + 'd','e','r','s','t','a','n','d','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','u','n','t','i','l','t','h','e','y','v','e','f', + 'a','d','e','d','B','u','t','t','r','u','s','t','m','e','i','n', + '2','0','y','e','a','r','s','y','o','u','l','l','l','o','o','k', + 'b','a','c','k','a','t','p','h','o','t','o','s','o','f','y','o', + 'u','r','s','e','l','f','a','n','d','r','e','c','a','l','l','i', + 'n','a','w','a','y','y','o','u','c','a','n','t','g','r','a','s', + 'p','n','o','w','h','o','w','m','u','c','h','p','o','s','s','i', + 'b','i','l','i','t','y','l','a','y','b','e','f','o','r','e','y', + 'o','u','a','n','d','h','o','w','f','a','b','u','l','o','u','s', + 'y','o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y', + 'o','u','a','r','e','n','o','t','a','s','f','a','t','a','s','y', + 'o','u','i','m','a','g','i','n','e','D','o','n','t','w','o','r', + 'r','y','a','b','o','u','t','t','h','e','f','u','t','u','r','e', + 'O','r','w','o','r','r','y','b','u','t','k','n','o','w','t','h', + 'a','t','K','u','r','t','V','o','n','n','e','g','u','t','s','C', + 'o','m','m','e','n','c','e','m','e','n','t','A','d','d','r','e', + 's','s','a','t','M','I','T','L','a','d','i','e','s','a','n','d', + 'g','e','n','t','l','e','m','e','n','o','f','t','h','e','c','l', + 'a','s','s','o','f','9','7','W','e','a','r','s','u','n','s','c', + 'r','e','e','n','I','f','I','c','o','u','l','d','o','f','f','e', + 'r','y','o','u','o','n','l','y','o','n','e','t','i','p','f','o', + 'r','t','h','e','f','u','t','u','r','e','s','u','n','s','c','r', + 'e','e','n','w','o','u','l','d','b','e','i','t','T','h','e','l', + 'o','n','g','t','e','r','m','b','e','n','e','f','i','t','s','o', + 'f','s','u','n','s','c','r','e','e','n','h','a','v','e','b','e', + 'e','n','p','r','o','v','e','d','b','y','s','c','i','e','n','t', + 'i','s','t','s','w','h','e','r','e','a','s','t','h','e','r','e', + 's','t','o','f','m','y','a','d','v','i','c','e','h','a','s','n', + 'o','b','a','s','i','s','m','o','r','e','r','e','l','i','a','b', + 'l','e','t','h','a','n','m','y','o','w','n','m','e','a','n','d', + 'e','r','i','n','g','e','x','p','e','r','i','e','n','c','e','I', + 'w','i','l','l','d','i','s','p','e','n','s','e','t','h','i','s', + 'a','d','v','i','c','e','n','o','w','E','n','j','o','y','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','O','h','n','e','v','e', + 'r','m','i','n','d','Y','o','u','w','i','l','l','n','o','t','u', + 'n','d','e','r','s','t','a','n','d','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','u','n','t','i','l','t','h','e','y','v','e', + 'f','a','d','e','d','B','u','t','t','r','u','s','t','m','e','i', + 'n','2','0','y','e','a','r','s','y','o','u','l','l','l','o','o', + 'k','b','a','c','k','a','t','p','h','o','t','o','s','o','f','y', + 'o','u','r','s','e','l','f','a','n','d','r','e','c','a','l','l', + 'i','n','a','w','a','y','y','o','u','c','a','n','t','g','r','a', + 's','p','n','o','w','h','o','w','m','u','c','h','p','o','s','s', + 'i','b','i','l','i','t','y','l','a','y','b','e','f','o','r','e', + 'y','o','u','a','n','d','h','o','w','f','a','b','u','l','o','u', + 's','y','o','u','r','e','a','l','l','y','l','o','o','k','e','d', + 'Y','o','u','a','r','e','n','o','t','a','s','f','a','t','a','s', + 'y','o','u','i','m','a','g','i','n','e','D','o','n','t','w','o', + 'r','r','y','a','b','o','u','t','t','h','e','f','u','t','u','r', + 'e','O','r','w','o','r','r','y','b','u','t','k','n','o','w','t', + 'h','a','t','t','s','C','o','m','m','e','n','c','e','m','e','n', + 't','A','d','d','r','e','s','s','a','t','M','I','T','L','a','d', + 'i','e','s','a','n','d','g','e','n','t','l','e','m','e','n','o', + 'f','t','h','e','c','l','a','s','s','o','f','9','7','W','e','a', + 'r','s','u','n','s','c','r','e','e','n','I','f','I','c','o','u', + 'l','d','o','f','f','e','r','y','o','u','o','n','l','y','o','n', + 'e','t','i','p','f','o','r','t','h','e','f','u','t','u','r','e', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','t','s','C','o', + 'm','m','e','n','c','e','m','e','n','t','A','d','d','r','e','s', + 's','a','t','M','I','T','L','a','d','i','e','s','a','n','d','g', + 'e','n','t','l','e','m','e','n','o','f','t','h','e','c','l','a', + 's','s','o','f','9','7','W','e','a','r','s','u','n','s','c','r', + 'e','e','n','I','f','I','c','o','u','l','d','o','f','f','e','r', + 'y','o','u','o','n','l','y','o','n','e','t','i','p','f','o','r', + 't','h','e','f','u','t','u','r','e','s','u','n','s','c','r','e', + 'e','n','w','o','u','l','d','b','e','i','t','T','h','e','l','o', + 'n','g','t','e','r','m','b','e','n','e','f','i','t','s','o','f', + 's','u','n','s','c','r','e','e','n','h','a','v','e','b','e','e', + 'n','p','r','o','v','e','d','b','y','s','c','i','e','n','t','i', + 's','t','s','w','h','e','r','e','a','s','t','h','e','r','e','s', + 't','o','f','m','y','a','d','v','i','c','e','h','a','s','n','o', + 'b','a','s','i','s','m','o','r','e','r','e','l','i','a','b','l', + 'e','t','h','a','n','m','y','o','w','n','m','e','a','n','d','e', + 'r','i','n','g','e','x','p','e','r','i','e','n','c','e','I','w', + 'i','l','l','d','i','s','p','e','n','s','e','t','h','i','s','a', + 'd','v','i','c','e','n','o','w','E','n','j','o','y','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','O','h','n','e','v','e','r', + 'm','i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n', + 'd','e','r','s','t','a','n','d','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','u','n','t','i','l','t','h','e','y','v','e','f', + 'a','d','e','d','B','u','t','t','r','u','s','t','m','e','i','n', + '2','0','y','e','a','r','s','y','o','u','l','l','l','o','o','k', + 'b','a','c','k','a','t','p','h','o','t','o','s','o','f','y','o', + 'u','r','s','e','l','f','a','n','d','r','e','c','a','l','l','i', + 'n','a','w','a','y','y','o','u','c','a','n','t','g','r','a','s', + 'p','n','o','w','h','o','w','m','u','c','h','p','o','s','s','i', + 'b','i','l','i','t','y','l','a','y','b','e','f','o','r','e','y', + 'o','u','a','n','d','h','o','w','f','a','b','u','l','o','u','s', + 'y','o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y', + 'o','u','a','r','e','n','o','t','a','s','f','a','t','a','s','y', + 'o','u','i','m','a','g','i','n','e','D','o','n','t','w','o','r', + 'r','y','a','b','o','u','t','t','h','e','f','u','t','u','r','e', + 'O','r','w','o','r','r','y','b','u','t','k','n','o','w','t','h', + 'a','t','K','u','r','t','V','o','n','n','e','g','u','t','s','C', + 'o','m','m','e','n','c','e','m','e','n','t','A','d','d','r','e', + 's','s','a','t','M','I','T','L','a','d','i','e','s','a','n','d', + 'g','e','n','t','l','e','m','e','n','o','f','t','h','e','c','l', + 'a','s','s','o','f','9','7','W','e','a','r','s','u','n','s','c', + 'r','e','e','n','I','f','I','c','o','u','l','d','o','f','f','e', + 'r','y','o','u','o','n','l','y','o','n','e','t','i','p','f','o', + 'r','t','h','e','f','u','t','u','r','e','s','u','n','s','c','r', + 'e','e','n','w','o','u','l','d','b','e','i','t','T','h','e','l', + 'o','n','g','t','e','r','m','b','e','n','e','f','i','t','s','o', + 'f','s','u','n','s','c','r','e','e','n','h','a','v','e','b','e', + 'e','n','p','r','o','v','e','d','b','y','s','c','i','e','n','t', + 'i','s','t','s','w','h','e','r','e','a','s','t','h','e','r','e', + 's','t','o','f','m','y','a','d','v','i','c','e','h','a','s','n', + 'o','b','a','s','i','s','m','o','r','e','r','e','l','i','a','b', + 'l','e','t','h','a','n','m','y','o','w','n','m','e','a','n','d', + 'e','r','i','n','g','e','x','p','e','r','i','e','n','c','e','I', + 'w','i','l','l','d','i','s','p','e','n','s','e','t','h','i','s', + 'a','d','v','i','c','e','n','o','w','E','n','j','o','y','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','O','h','n','e','v','e', + 'r','m','i','n','d','Y','o','u','w','i','l','l','n','o','t','u', + 'n','d','e','r','s','t','a','n','d','t','h','e','p','o','w','e', + 'r','a','K','u','r','t','V','o','n','n','e','g','u','t','s','C', + 'o','m','m','e','n','c','e','m','e','n','t','A','d','d','r','e', + 's','s','a','t','M','I','T','L','a','d','i','e','s','a','n','d', + 'g','e','n','t','l','e','m','e','n','o','f','t','h','e','c','l', + 'a','s','s','o','f','9','7','W','e','a','r','s','u','n','s','c', + 'r','e','e','n','I','f','I','c','o','u','l','d','o','f','f','e', + 'r','y','o','u','o','n','l','y','o','n','e','t','i','p','f','o', + 'r','t','h','e','f','u','t','u','r','e','s','u','n','s','c','r', + 'e','e','n','w','o','u','l','d','b','e','i','t','T','h','e','l', + 'o','n','g','t','e','r','m','b','e','n','e','f','i','t','s','o', + 'f','s','u','n','s','c','r','e','e','n','h','a','v','e','b','e', + 'e','n','p','r','o','v','e','d','b','y','s','c','i','e','n','t', + 'i','s','t','s','w','h','e','r','e','a','s','t','h','e','r','e', + 's','t','o','f','m','y','a','d','v','i','c','e','h','a','s','n', + 'o','b','a','s','i','s','m','o','r','e','r','e','l','i','a','b', + 'l','e','t','h','a','n','m','y','o','w','n','m','e','a','n','d', + 'e','r','i','n','g','e','x','p','e','r','i','e','n','c','e','I', + 'w','i','l','l','d','i','s','p','e','n','s','e','t','h','i','s', + 'a','d','v','i','c','e','n','o','w','E','n','j','o','y','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','O','h','n','e','v','e', + 'r','m','i','n','d','Y','o','u','w','i','l','l','n','o','t','u', + 'n','d','e','r','s','t','a','n','d','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','u','n','t','i','l','t','h','e','y','v','e', + 'f','a','d','e','d','B','u','t','t','r','u','s','t','m','e','i', + 'n','2','0','y','e','a','r','s','y','o','u','l','l','l','o','o', + 'k','b','a','c','k','a','t','p','h','o','t','o','s','o','f','y', + 'o','u','r','s','e','l','f','a','n','d','r','e','c','a','l','l', + 'i','n','a','w','a','y','y','o','u','c','a','n','t','g','r','a', + 's','p','n','o','w','h','o','w','m','u','c','h','p','o','s','s', + 'i','b','i','l','i','t','y','l','a','y','b','e','f','o','r','e', + 'y','o','u','a','n','d','h','o','w','f','a','b','u','l','o','u', + 's','y','o','u','r','e','a','l','l','y','l','o','o','k','e','d', + 'Y','o','u','a','r','e','n','o','t','a','s','f','a','t','a','s', + 'y','o','u','i','m','a','g','i','n','e','D','o','n','t','w','o', + 'r','r','y','a','b','o','u','t','t','h','e','f','u','t','u','r', + 'e','O','r','w','o','r','r','y','b','u','t','k','n','o','w','t', + 'h','a','t','K','u','r','t','V','o','n','n','e','g','u','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','K', + 'u','r','t','V','o','n','n','e','g','u','t','s','C','o','m','m', + 'e','n','c','e','m','e','n','t','A','d','d','r','e','s','s','a', + 't','M','I','T','L','a','d','i','e','s','a','n','d','g','e','n', + 't','l','e','m','e','n','o','f','t','h','e','c','l','a','s','s', + 'o','f','9','7','W','e','a','r','s','u','n','s','c','r','e','e', + 'n','I','f','I','c','o','u','l','d','o','f','f','e','r','y','o', + 'u','o','n','l','y','o','n','e','t','i','p','f','o','r','t','h', + 'e','f','u','t','u','r','e','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','K', + 'u','r','t','V','o','n','n','e','g','u','t','s','C','o','m','m', + 'e','n','c','e','m','e','n','t','A','d','d','r','e','s','s','a', + 't','M','I','T','L','a','d','i','e','s','a','n','d','g','e','n', + 't','l','e','m','e','n','o','f','t','h','e','c','l','a','s','s', + 'o','f','9','7','W','e','a','r','s','u','n','s','c','r','e','e', + 'n','I','f','I','c','o','u','l','d','o','f','f','e','r','y','o', + 'u','o','n','l','y','o','n','e','t','i','p','f','o','r','t','h', + 'e','f','u','t','u','r','e','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'K','u','r','t','V','o','n','n','e','g','u','t','s','C','o','m', + 'm','e','n','c','e','m','e','n','t','A','d','d','r','e','s','s', + 'a','t','M','I','T','L','a','d','i','e','s','a','n','d','g','e', + 'n','t','l','e','m','e','n','o','f','t','h','e','c','l','a','s', + 's','o','f','9','7','W','e','a','r','s','u','n','s','c','r','e', + 'e','n','I','f','I','c','o','u','l','d','o','f','f','e','r','y', + 'o','u','o','n','l','y','o','n','e','t','i','p','f','o','r','t', + 'h','e','f','u','t','u','r','e','s','u','n','s','c','r','e','e', + 'n','w','o','u','l','d','b','e','i','t','T','h','e','l','o','n', + 'g','t','e','r','m','b','e','n','e','f','i','t','s','o','f','s', + 'u','n','s','c','r','e','e','n','h','a','v','e','b','e','e','n', + 'p','r','o','v','e','d','b','y','s','c','i','e','n','t','i','s', + 't','s','w','h','e','r','e','a','s','t','h','e','r','e','s','t', + 'o','f','m','y','a','d','v','i','c','e','h','a','s','n','o','b', + 'a','s','i','s','m','o','r','e','r','e','l','i','a','b','l','e', + 't','h','a','n','m','y','o','w','n','m','e','a','n','d','e','r', + 'i','n','g','e','x','p','e','r','i','e','n','c','e','I','w','i', + 'l','l','d','i','s','p','e','n','s','e','t','h','i','s','a','d', + 'v','i','c','e','n','o','w','E','n','j','o','y','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','O','h','n','e','v','e','r','m', + 'i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d', + 'e','r','s','t','a','n','d','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','u','n','t','i','l','t','h','e','y','v','e','f','a', + 'd','e','d','B','u','t','t','r','u','s','t','m','e','i','n','2', + '0','y','e','a','r','s','y','o','u','l','l','l','o','o','k','b', + 'a','c','k','a','t','p','h','o','t','o','s','o','f','y','o','u', + 'r','s','e','l','f','a','n','d','r','e','c','a','l','l','i','n', + 'a','w','a','y','y','o','u','c','a','n','t','g','r','a','s','p', + 'n','o','w','h','o','w','m','u','c','h','p','o','s','s','i','b', + 'i','l','i','t','y','l','a','y','b','e','f','o','r','e','y','o', + 'u','a','n','d','h','o','w','f','a','b','u','l','o','u','s','y', + 'o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o', + 'u','a','r','e','n','o','t','a','s','f','a','t','a','s','y','o', + 'u','i','m','a','g','i','n','e','D','o','n','t','w','o','r','r', + 'y','a','b','o','u','t','t','h','e','f','u','t','u','r','e','O', + 'r','w','o','r','r','y','b','u','t','k','n','o','w','t','h','a', + 't','K','u','r','t','V','o','n','n','e','g','u','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','n','d','b','e','a','u','t','y', + 'o','f','y','o','u','r','y','o','u','t','h','u','n','t','i','l', + 't','h','e','y','v','e','f','a','d','e','d','B','u','t','t','r', + 'u','s','t','m','e','i','n','2','0','y','e','a','r','s','y','o', + 'u','l','l','l','o','o','k','b','a','c','k','a','t','p','h','o', + 't','o','s','o','f','y','o','u','r','s','e','l','f','a','n','d', + 'r','e','c','a','l','l','i','n','a','w','a','y','y','o','u','c', + 'a','n','t','g','r','a','s','p','n','o','w','h','o','w','m','u', + 'c','h','p','o','s','s','i','b','i','l','i','t','y','l','a','y', + 'b','e','f','o','r','e','y','o','u','a','n','d','h','o','w','f', + 'a','b','u','l','o','u','s','y','o','u','r','e','a','l','l','y', + 'l','o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a', + 's','f','a','t','a','s','y','o','u','i','m','a','g','i','n','e', + 'D','o','n','t','w','o','r','r','y','a','b','o','u','t','t','h', + 'e','f','u','t','u','r','e','O','r','w','o','r','r','y','b','u', + 't','k','n','o','w','t','h','a','t','s','u','n','s','c','r','e', + 'e','n','w','o','u','l','d','b','e','i','t','T','h','e','l','o', + 'n','g','t','e','r','m','b','e','n','e','f','i','t','s','o','f', + 's','u','n','s','c','r','e','e','n','h','a','v','e','b','e','e', + 'n','p','r','o','v','e','d','b','y','s','c','i','e','n','t','i', + 's','t','s','w','h','e','r','e','a','s','t','h','e','r','e','s', + 't','o','f','m','y','a','d','v','i','c','e','h','a','s','n','o', + 'b','a','s','i','s','m','o','r','e','r','e','l','i','a','b','l', + 'e','t','h','a','n','m','y','o','w','n','m','e','a','n','d','e', + 'r','i','n','g','e','x','p','e','r','i','e','n','c','e','I','w', + 'i','l','l','d','i','s','p','e','n','s','e','t','h','i','s','a', + 'd','v','i','c','e','n','o','w','E','n','j','o','y','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','O','h','n','e','v','e','r', + 'm','i','n','d','Y','o','u','w','i','l','l','n','o','t','u','n', + 'd','e','r','s','t','a','n','d','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','u','n','t','i','l','t','h','e','y','v','e','f', + 'a','d','e','d','B','u','t','t','r','u','s','t','m','e','i','n', + '2','0','y','e','a','r','s','y','o','u','l','l','l','o','o','k', + 'b','a','c','k','a','t','p','h','o','t','o','s','o','f','y','o', + 'u','r','s','e','l','f','a','n','d','r','e','c','a','l','l','i', + 'n','a','w','a','y','y','o','u','c','a','n','t','g','r','a','s', + 'p','n','o','w','h','o','w','m','u','c','h','p','o','s','s','i', + 'b','i','l','i','t','y','l','a','y','b','e','f','o','r','e','y', + 'o','u','a','n','d','h','o','w','f','a','b','u','l','o','u','s', + 'y','o','u','r','e','a','l','l','y','l','o','o','k','e','d','Y', + 'o','u','a','r','e','n','o','t','a','s','f','a','t','a','s','y', + 'o','u','i','m','a','g','i','n','e','D','o','n','t','w','o','r', + 'r','y','a','b','o','u','t','t','h','e','f','u','t','u','r','e', + 'O','r','w','o','r','r','y','b','u','t','k','n','o','w','t','h', + 'a','t','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','u','n','t','i','l','t','h','e','y','v','e', + 'f','a','d','e','d','B','u','t','t','r','u','s','t','m','e','i', + 'n','2','0','y','e','a','r','s','y','o','u','l','l','l','o','o', + 'k','b','a','c','k','a','t','p','h','o','t','o','s','o','f','y', + 'o','u','r','s','e','l','f','a','n','d','r','e','c','a','l','l', + 'i','n','a','w','a','y','y','o','u','c','a','n','t','g','r','a', + 's','p','n','o','w','h','o','w','m','u','c','h','p','o','s','s', + 'i','b','i','l','i','t','y','l','a','y','b','e','f','o','r','e', + 'y','o','u','a','n','d','h','o','w','f','a','b','u','l','o','u', + 's','y','o','u','r','e','a','l','l','y','l','o','o','k','e','d', + 'Y','o','u','a','r','e','n','o','t','a','s','f','a','t','a','s', + 'y','o','u','i','m','a','g','i','n','e','D','o','n','t','w','o', + 'r','r','y','a','b','o','u','t','t','h','e','f','u','t','u','r', + 'e','O','r','w','o','r','r','y','b','u','t','k','n','o','w','t', + 'h','a','t','s','u','n','s','c','r','e','e','n','w','o','u','l', + 'd','b','e','i','t','T','h','e','l','o','n','g','t','e','r','m', + 'b','e','n','e','f','i','t','s','o','f','s','u','n','s','c','r', + 'e','e','n','h','a','v','e','b','e','e','n','p','r','o','v','e', + 'd','b','y','s','c','i','e','n','t','i','s','t','s','w','h','e', + 'r','e','a','s','t','h','e','r','e','s','t','o','f','m','y','a', + 'd','v','i','c','e','h','a','s','n','o','b','a','s','i','s','m', + 'o','r','e','r','e','l','i','a','b','l','e','t','h','a','n','m', + 'y','o','w','n','m','e','a','n','d','e','r','i','n','g','e','x', + 'p','e','r','i','e','n','c','e','I','w','i','l','l','d','i','s', + 'p','e','n','s','e','t','h','i','s','a','d','v','i','c','e','n', + 'o','w','E','n','j','o','y','t','h','e','p','o','w','e','r','a', + 'n','d','b','e','a','u','t','y','o','f','y','o','u','r','y','o', + 'u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y','o', + 'u','w','i','l','l','n','o','t','u','n','d','e','r','s','t','a', + 'n','d','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','u','n', + 't','i','l','t','h','e','y','v','e','f','a','d','e','d','B','u', + 't','t','r','u','s','t','m','e','i','n','2','0','y','e','a','r', + 's','y','o','u','l','l','l','o','o','k','b','a','c','k','a','t', + 'p','h','o','t','o','s','o','f','y','o','u','r','s','e','l','f', + 'a','n','d','r','e','c','a','l','l','i','n','a','w','a','y','y', + 'o','u','c','a','n','t','g','r','a','s','p','n','o','w','h','o', + 'w','m','u','c','h','p','o','s','s','i','b','i','l','i','t','y', + 'l','a','y','b','e','f','o','r','e','y','o','u','a','n','d','h', + 'o','w','f','a','b','u','l','o','u','s','y','o','u','r','e','a', + 'l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e','n', + 'o','t','a','s','f','a','t','a','s','y','o','u','i','m','a','g', + 'i','n','e','D','o','n','t','w','o','r','r','y','a','b','o','u', + 't','t','h','e','f','u','t','u','r','e','O','r','w','o','r','r', + 'y','b','u','t','k','n','o','w','t','h','a','t','b','u','t','k', + 'n','o','w','t','h','a','t','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 't','s','C','o','m','m','e','n','c','e','m','e','n','t','A','d', + 'd','r','e','s','s','a','t','M','I','T','L','a','d','i','e','s', + 'a','n','d','g','e','n','t','l','e','m','e','n','o','f','t','h', + 'e','c','l','a','s','s','o','f','9','7','W','e','a','r','s','u', + 'n','s','c','r','e','e','n','I','f','I','c','o','u','l','d','o', + 'f','f','e','r','y','o','u','o','n','l','y','o','n','e','t','i', + 'p','f','o','r','t','h','e','f','u','t','u','r','e','s','u','n', + 's','c','r','e','e','n','w','o','u','l','d','b','e','i','t','T', + 'h','e','l','o','n','g','t','e','r','m','b','e','n','e','f','i', + 't','s','o','f','s','u','n','s','c','r','e','e','n','h','a','v', + 'e','b','e','e','n','p','r','o','v','e','d','b','y','s','c','i', + 'e','n','t','i','s','t','s','w','h','e','r','e','a','s','t','h', + 'e','r','e','s','t','o','f','m','y','a','d','v','i','c','e','h', + 'a','s','n','o','b','a','s','i','s','m','o','r','e','r','e','l', + 'i','a','b','l','e','t','h','a','n','m','y','o','w','n','m','e', + 'a','n','d','e','r','i','n','g','e','x','p','e','r','i','e','n', + 'c','e','I','w','i','l','l','d','i','s','p','e','n','s','e','t', + 'h','i','s','a','d','v','i','c','e','n','o','w','E','n','j','o', + 'y','t','h','e','p','o','w','e','r','a','n','d','b','e','a','u', + 't','y','o','f','y','o','u','r','y','o','u','t','h','O','h','n', + 'e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n', + 'o','t','u','n','d','e','r','s','t','a','n','d','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','u','n','t','i','l','t','h','e', + 'y','v','e','f','a','d','e','d','B','u','t','t','r','u','s','t', + 'm','e','i','n','2','0','y','e','a','r','s','y','o','u','l','l', + 'l','o','o','k','b','a','c','k','a','t','p','h','o','t','o','s', + 'o','f','y','o','u','r','s','e','l','f','a','n','d','r','e','c', + 'a','l','l','i','n','a','w','a','y','y','o','u','c','a','n','t', + 'g','r','a','s','p','n','o','w','h','o','w','m','u','c','h','p', + 'o','s','s','i','b','i','l','i','t','y','l','a','y','b','e','f', + 'o','r','e','y','o','u','a','n','d','h','o','w','f','a','b','u', + 'l','o','u','s','y','o','u','r','e','a','l','l','y','l','o','o', + 'k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a', + 't','a','s','y','o','u','i','m','a','g','i','n','e','D','o','n', + 't','w','o','r','r','y','a','b','o','u','t','t','h','e','f','u', + 't','u','r','e','O','r','w','o','r','r','y','b','u','t','k','n', + 'o','w','t','h','a','t','K','u','r','t','V','o','n','n','e','g', + 'u','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','s','u', + 'n','s','c','r','e','e','n','w','o','u','l','d','b','e','i','t', + 'T','h','e','l','o','n','g','t','e','r','m','b','e','n','e','f', + 'i','t','s','o','f','s','u','n','s','c','r','e','e','n','h','a', + 'v','e','b','e','e','n','p','r','o','v','e','d','b','y','s','c', + 'i','e','n','t','i','s','t','s','w','h','e','r','e','a','s','t', + 'h','e','r','e','s','t','o','f','m','y','a','d','v','i','c','e', + 'h','a','s','n','o','b','a','s','i','s','m','o','r','e','r','e', + 'l','i','a','b','l','e','t','h','a','n','m','y','o','w','n','m', + 'e','a','n','d','e','r','i','n','g','e','x','p','e','r','i','e', + 'n','c','e','I','w','i','l','l','d','i','s','p','e','n','s','e', + 't','h','i','s','a','d','v','i','c','e','n','o','w','E','n','j', + 'o','y','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','O','h', + 'n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l', + 'n','o','t','u','n','d','e','r','s','t','a','n','d','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','u','n','t','i','l','t','h', + 'e','y','v','e','f','a','d','e','d','B','u','t','t','r','u','s', + 't','m','e','i','n','2','0','y','e','a','r','s','y','o','u','l', + 'l','l','o','o','k','b','a','c','k','a','t','p','h','o','t','o', + 's','o','f','y','o','u','r','s','e','l','f','a','n','d','r','e', + 'c','a','l','l','i','n','a','w','a','y','y','o','u','c','a','n', + 't','g','r','a','s','p','n','o','w','h','o','w','m','u','c','h', + 'p','o','s','s','i','b','i','l','i','t','y','l','a','y','b','e', + 'f','o','r','e','y','o','u','a','n','d','h','o','w','f','a','b', + 'u','l','o','u','s','y','o','u','r','e','a','l','l','y','l','o', + 'o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f', + 'a','t','a','s','y','o','u','i','m','a','g','i','n','e','D','o', + 'n','t','w','o','r','r','y','a','b','o','u','t','t','h','e','f', + 'u','t','u','r','e','O','r','w','o','r','r','y','b','u','t','k', + 'n','o','w','t','h','a','t','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + '\n', 'l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','\n', 'l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 't','s','C','o','m','m','e','n','c','e','m','e','n','t','A','d', + 'd','r','e','s','s','a','t','M','I','T','L','a','d','i','e','s', + 'a','n','d','g','e','n','t','l','e','m','e','n','o','f','t','h', + 'e','c','l','a','s','s','o','f','9','7','W','e','a','r','s','u', + 'n','s','c','r','e','e','n','I','f','I','c','o','u','l','d','o', + 'f','f','e','r','y','o','u','o','n','l','y','o','n','e','t','i', + 'p','f','o','r','t','h','e','f','u','t','u','r','e','s','u','n', + 's','c','r','e','e','n','w','o','u','l','d','b','e','i','t','T', + 'h','e','l','o','n','g','t','e','r','m','b','e','n','e','f','i', + 't','s','o','f','s','u','n','s','c','r','e','e','n','h','a','v', + 'e','b','e','e','n','p','r','o','v','e','d','b','y','s','c','i', + 'e','n','t','i','s','t','s','w','h','e','r','e','a','s','t','h', + 'e','r','e','s','t','o','f','m','y','a','d','v','i','c','e','h', + 'a','s','n','o','b','a','s','i','s','m','o','r','e','r','e','l', + 'i','a','b','l','e','t','h','a','n','m','y','o','w','n','m','e', + 'a','n','d','e','r','i','n','g','e','x','p','e','r','i','e','n', + 'c','e','I','w','i','l','l','d','i','s','p','e','n','s','e','t', + 'h','i','s','a','d','v','i','c','e','n','o','w','E','n','j','o', + 'y','t','h','e','p','o','w','e','r','a','n','d','b','e','a','u', + 't','y','o','f','y','o','u','r','y','o','u','t','h','O','h','n', + 'e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n', + 'o','t','u','n','d','e','r','s','t','a','n','d','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','u','n','t','i','l','t','h','e', + 'y','v','e','f','a','d','e','d','B','u','t','t','r','u','s','t', + 'm','e','i','n','2','0','y','e','a','r','s','y','o','u','l','l', + 'l','o','o','k','b','a','c','k','a','t','p','h','o','t','o','s', + 'o','f','y','o','u','r','s','e','l','f','a','n','d','r','e','c', + 'a','l','l','i','n','a','w','a','y','y','o','u','c','a','n','t', + 'g','r','a','s','p','n','o','w','h','o','w','m','u','c','h','p', + 'o','s','s','i','b','i','l','i','t','y','l','a','y','b','e','f', + 'o','r','e','y','o','u','a','n','d','h','o','w','f','a','b','u', + 'l','o','u','s','y','o','u','r','e','a','l','l','y','l','o','o', + 'k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a', + 't','a','s','y','o','u','i','m','a','g','i','n','e','D','o','n', + 't','w','o','r','r','y','a','b','o','u','t','t','h','e','f','u', + 't','u','r','e','O','r','w','o','r','r','y','b','u','t','k','n', + 'o','w','t','h','a','t','K','u','r','t','V','o','n','n','e','g', + 'u','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','s','u', + 'n','s','c','r','e','e','n','w','o','u','l','d','b','e','i','t', + 'T','h','e','l','o','n','g','t','e','r','m','b','e','n','e','f', + 'i','t','s','o','f','s','u','n','s','c','r','e','e','n','h','a', + 'v','e','b','e','e','n','p','r','o','v','e','d','b','y','s','c', + 'i','e','n','t','i','s','t','s','w','h','e','r','e','a','s','t', + 'h','e','r','e','s','t','o','f','m','y','a','d','v','i','c','e', + 'h','a','s','n','o','b','a','s','i','s','m','o','r','e','r','e', + 'l','i','a','b','l','e','t','h','a','n','m','y','o','w','n','m', + 'e','a','n','d','e','r','i','n','g','e','x','p','e','r','i','e', + 'n','c','e','I','w','i','l','l','d','i','s','p','e','n','s','e', + 't','h','i','s','a','d','v','i','c','e','n','o','w','E','n','j', + 'o','y','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','O','h', + 'n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l', + 'n','o','t','u','n','d','e','r','s','t','a','n','d','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','u','n','t','i','l','t','h', + 'e','y','v','e','f','a','d','e','d','B','u','t','t','r','u','s', + 't','m','e','i','n','2','0','y','e','a','r','s','y','o','u','l', + 'l','l','o','o','k','b','a','c','k','a','t','p','h','o','t','o', + 's','o','f','y','o','u','r','s','e','l','f','a','n','d','r','e', + 'c','a','l','l','i','n','a','w','a','y','y','o','u','c','a','n', + 't','g','r','a','s','p','n','o','w','h','o','w','m','u','c','h', + 'p','o','s','s','i','b','i','l','i','t','y','l','a','y','b','e', + 'f','o','r','e','y','o','u','a','n','d','h','o','w','f','a','b', + 'u','l','o','u','s','y','o','u','r','e','a','l','l','y','l','o', + 'o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f', + 'a','t','a','s','y','o','u','i','m','a','g','i','n','e','D','o', + 'n','t','w','o','r','r','y','a','b','o','u','t','t','h','e','f', + 'u','t','u','r','e','O','r','w','o','r','r','y','b','u','t','k', + 'n','o','w','t','h','a','t','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + '\n', 'l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','\n', 'l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','K','u','r','t','V','o','n','n','e','g','u','t', + 's','C','o','m','m','e','n','c','e','m','e','n','t','A','d','d', + 'r','e','s','s','a','t','M','I','T','L','a','d','i','e','s','a', + 'n','d','g','e','n','t','l','e','m','e','n','o','f','t','h','e', + 'c','l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','s','u','n','s', + 'c','r','e','e','n','w','o','u','l','d','b','e','i','t','T','h', + 'e','l','o','n','g','t','e','r','m','b','e','n','e','f','i','t', + 's','o','f','s','u','n','s','c','r','e','e','n','h','a','v','e', + 'b','e','e','n','p','r','o','v','e','d','b','y','s','c','i','e', + 'n','t','i','s','t','s','w','h','e','r','e','a','s','t','h','e', + 'r','e','s','t','o','f','m','y','a','d','v','i','c','e','h','a', + 's','n','o','b','a','s','i','s','m','o','r','e','r','e','l','i', + 'a','b','l','e','t','h','a','n','m','y','o','w','n','m','e','a', + 'n','d','e','r','i','n','g','e','x','p','e','r','i','e','n','c', + 'e','I','w','i','l','l','d','i','s','p','e','n','s','e','t','h', + 'i','s','a','d','v','i','c','e','n','o','w','E','n','j','o','y', + 't','h','e','p','o','w','e','r','a','n','d','b','e','a','u','t', + 'y','o','f','y','o','u','r','y','o','u','t','h','O','h','n','e', + 'v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n','o', + 't','u','n','d','e','r','s','t','a','n','d','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','u','n','t','i','l','t','h','e','y', + 'v','e','f','a','d','e','d','B','u','t','t','r','u','s','t','m', + 'e','i','n','2','0','y','e','a','r','s','y','o','u','l','l','l', + 'o','o','k','b','a','c','k','a','t','p','h','o','t','o','s','o', + 'f','y','o','u','r','s','e','l','f','a','n','d','r','e','c','a', + 'l','l','i','n','a','w','a','y','y','o','u','c','a','n','t','g', + 'r','a','s','p','n','o','w','h','o','w','m','u','c','h','p','o', + 's','s','i','b','i','l','i','t','y','l','a','y','b','e','f','o', + 'r','e','y','o','u','a','n','d','h','o','w','f','a','b','u','l', + 'o','u','s','y','o','u','r','e','a','l','l','y','l','o','o','k', + 'e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a','t', + 'a','s','y','o','u','i','m','a','g','i','n','e','D','o','n','t', + 'w','o','r','r','y','a','b','o','u','t','t','h','e','f','u','t', + 'u','r','e','O','r','w','o','r','r','y','b','u','t','k','n','o', + 'w','t','h','a','t','K','u','r','t','V','o','n','n','e','g','u', + 't','s','C','o','m','m','e','n','c','e','m','e','n','t','A','d', + 'd','r','e','s','s','a','t','M','I','T','L','a','d','i','e','s', + 'a','n','d','g','e','n','t','l','e','m','e','n','o','f','t','h', + 'e','c','l','a','s','s','o','f','9','7','W','e','a','r','s','u', + 'n','s','c','r','e','e','n','I','f','I','c','o','u','l','d','o', + 'f','f','e','r','y','o','u','o','n','l','y','o','n','e','t','i', + 'p','f','o','r','t','h','e','f','u','t','u','r','e','s','u','n', + 's','c','r','e','e','n','w','o','u','l','d','b','e','i','t','T', + 'h','e','l','o','n','g','t','e','r','m','b','e','n','e','f','i', + 't','s','o','f','s','u','n','s','c','r','e','e','n','h','a','v', + 'e','b','e','e','n','p','r','o','v','e','d','b','y','s','c','i', + 'e','n','t','i','s','t','s','w','h','e','r','e','a','s','t','h', + 'e','r','e','s','t','o','f','m','y','a','d','v','i','c','e','h', + 'a','s','n','o','b','a','s','i','s','m','o','r','e','r','e','l', + 'i','a','b','l','e','t','h','a','n','m','y','o','w','n','m','e', + 'a','n','d','e','r','i','n','g','e','x','p','e','r','i','e','n', + 'c','e','I','w','i','l','l','d','i','s','p','e','n','s','e','t', + 'h','i','s','a','d','v','i','c','e','n','o','w','E','n','j','o', + 'y','t','h','e','p','o','w','e','r','a','n','d','b','e','a','u', + 't','y','o','f','y','o','u','r','y','o','u','t','h','O','h','n', + 'e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l','n', + 'o','t','u','n','d','e','r','s','t','a','n','d','t','h','e','p', + 'o','w','e','r','a','n','d','b','e','a','u','t','y','o','f','y', + 'o','u','r','y','o','u','t','h','u','n','t','i','l','t','h','e', + 'y','v','e','f','a','d','e','d','B','u','t','t','r','u','s','t', + 'm','e','i','n','2','0','y','e','a','r','s','y','o','u','l','l', + 'l','o','o','k','b','a','c','k','a','t','p','h','o','t','o','s', + 'o','f','y','o','u','r','s','e','l','f','a','n','d','r','e','c', + 'a','l','l','i','n','a','w','a','y','y','o','u','c','a','n','t', + 'g','r','a','s','p','n','o','w','h','o','w','m','u','c','h','p', + 'o','s','s','i','b','i','l','i','t','y','l','a','y','b','e','f', + 'o','r','e','y','o','u','a','n','d','h','o','w','f','a','b','u', + 'l','o','u','s','y','o','u','r','e','a','l','l','y','l','o','o', + 'k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f','a', + 't','a','s','y','o','u','i','m','a','g','i','n','e','D','o','n', + 't','w','o','r','r','y','a','b','o','u','t','t','h','e','f','u', + 't','u','r','e','O','r','w','o','r','r','y','b','u','t','k','n', + 'o','w','t','h','a','t','K','u','r','t','V','o','n','n','e','g', + 'u','t','s','C','o','m','m','e','n','c','e','m','e','n','t','A', + 'd','d','r','e','s','s','a','t','M','I','T','L','a','d','i','e', + 's','a','n','d','g','e','n','t','l','e','m','e','n','o','f','t', + 'h','e','c','l','a','s','s','o','f','9','7','W','e','a','r','s', + 'u','n','s','c','r','e','e','n','I','f','I','c','o','u','l','d', + 'o','f','f','e','r','y','o','u','o','n','l','y','o','n','e','t', + 'i','p','f','o','r','t','h','e','f','u','t','u','r','e','s','u', + 'n','s','c','r','e','e','n','w','o','u','l','d','b','e','i','t', + 'T','h','e','l','o','n','g','t','e','r','m','b','e','n','e','f', + 'i','t','s','o','f','s','u','n','s','c','r','e','e','n','h','a', + 'v','e','b','e','e','n','p','r','o','v','e','d','b','y','s','c', + 'i','e','n','t','i','s','t','s','w','h','e','r','e','a','s','t', + 'h','e','r','e','s','t','o','f','m','y','a','d','v','i','c','e', + 'h','a','s','n','o','b','a','s','i','s','m','o','r','e','r','e', + 'l','i','a','b','l','e','t','h','a','n','m','y','o','w','n','m', + 'e','a','n','d','e','r','i','n','g','e','x','p','e','r','i','e', + 'n','c','e','I','w','i','l','l','d','i','s','p','e','n','s','e', + 't','h','i','s','a','d','v','i','c','e','n','o','w','E','n','j', + 'o','y','t','h','e','p','o','w','e','r','a','n','d','b','e','a', + 'u','t','y','o','f','y','o','u','r','y','o','u','t','h','O','h', + 'n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l','l', + 'n','o','t','u','n','d','e','r','s','t','a','n','d','t','h','e', + 'p','o','w','e','r','a','n','d','b','e','a','u','t','y','o','f', + 'y','o','u','r','y','o','u','t','h','u','n','t','i','l','t','h', + 'e','y','v','e','f','a','d','e','d','B','u','t','t','r','u','s', + 't','m','e','i','n','2','0','y','e','a','r','s','y','o','u','l', + 'l','l','o','o','k','b','a','c','k','a','t','p','h','o','t','o', + 's','o','f','y','o','u','r','s','e','l','f','a','n','d','r','e', + 'c','a','l','l','i','n','a','w','a','y','y','o','u','c','a','n', + 't','g','r','a','s','p','n','o','w','h','o','w','m','u','c','h', + 'p','o','s','s','i','b','i','l','i','t','y','l','a','y','b','e', + 'f','o','r','e','y','o','u','a','n','d','h','o','w','f','a','b', + 'u','l','o','u','s','y','o','u','r','e','a','l','l','y','l','o', + 'o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s','f', + 'a','t','a','s','y','o','u','i','m','a','g','i','n','e','D','o', + 'n','t','w','o','r','r','y','a','b','o','u','t','t','h','e','f', + 'u','t','u','r','e','O','r','w','o','r','r','y','b','u','t','k', + 'n','o','w','t','h','a','t','s','u','n','s','c','r','e','e','n', + 'w','o','u','l','d','b','e','i','t','T','h','e','l','o','n','g', + 't','e','r','m','b','e','n','e','f','i','t','s','o','f','s','u', + 'n','s','c','r','e','e','n','h','a','v','e','b','e','e','n','p', + 'r','o','v','e','d','b','y','s','c','i','e','n','t','i','s','t', + 's','w','h','e','r','e','a','s','t','h','e','r','e','s','t','o', + 'f','m','y','a','d','v','i','c','e','h','a','s','n','o','b','a', + 's','i','s','m','o','r','e','r','e','l','i','a','b','l','e','t', + 'h','a','n','m','y','o','w','n','m','e','a','n','d','e','r','i', + 'n','g','e','x','p','e','r','i','e','n','c','e','I','w','i','l', + 'l','d','i','s','p','e','n','s','e','t','h','i','s','a','d','v', + 'i','c','e','n','o','w','E','n','j','o','y','t','h','e','p','o', + 'w','e','r','a','n','d','b','e','a','u','t','y','o','f','y','o', + 'u','r','y','o','u','t','h','O','h','n','e','v','e','r','m','i', + 'n','d','Y','o','u','w','i','l','l','n','o','t','u','n','d','e', + 'r','s','t','a','n','d','t','h','e','p','o','w','e','r','a','n', + 'd','b','e','a','u','t','y','o','f','y','o','u','r','y','o','u', + 't','h','u','n','t','i','l','t','h','e','y','v','e','f','a','d', + 'e','d','B','u','t','t','r','u','s','t','m','e','i','n','2','0', + 'y','e','a','r','s','y','o','u','l','l','l','o','o','k','b','a', + 'c','k','a','t','p','h','o','t','o','s','o','f','y','o','u','r', + 's','e','l','f','a','n','d','r','e','c','a','l','l','i','n','a', + 'w','a','y','y','o','u','c','a','n','t','g','r','a','s','p','n', + 'o','w','h','o','w','m','u','c','h','p','o','s','s','i','b','i', + 'l','i','t','y','l','a','y','b','e','f','o','r','e','y','o','u', + 'a','n','d','h','o','w','f','a','b','u','l','o','u','s','y','o', + 'u','r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u', + 'a','r','e','n','o','t','a','s','f','a','t','a','s','y','o','u', + 'i','m','a','g','i','n','e','D','o','n','t','w','o','r','r','y', + 'a','b','o','u','t','t','h','e','f','u','t','u','r','e','O','r', + 'w','o','r','r','y','b','u','t','k','n','o','w','t','h','a','t', + '\n', 'l','a','s','s','o','f','9','7','W','e','a','r','s','u','n', + 's','c','r','e','e','n','I','f','I','c','o','u','l','d','o','f', + 'f','e','r','y','o','u','o','n','l','y','o','n','e','t','i','p', + 'f','o','r','t','h','e','f','u','t','u','r','e','K','u','r','t', + 'V','o','n','n','e','g','u','t','s','C','o','m','m','e','n','c', + 'e','m','e','n','t','A','d','d','r','e','s','s','a','t','M','I', + 'T','L','a','d','i','e','s','a','n','d','g','e','n','t','l','e', + 'm','e','n','o','f','t','h','e','c','l','a','s','s','o','f','9', + '7','W','e','a','r','s','u','n','s','c','r','e','e','n','I','f', + 'I','c','o','u','l','d','o','f','f','e','r','y','o','u','o','n', + 'l','y','o','n','e','t','i','p','f','o','r','t','h','e','f','u', + 't','u','r','e','s','u','n','s','c','r','e','e','n','w','o','u', + 'l','d','b','e','i','t','T','h','e','l','o','n','g','t','e','r', + 'm','b','e','n','e','f','i','t','s','o','f','s','u','n','s','c', + 'r','e','e','n','h','a','v','e','b','e','e','n','p','r','o','v', + 'e','d','b','y','s','c','i','e','n','t','i','s','t','s','w','h', + 'e','r','e','a','s','t','h','e','r','e','s','t','o','f','m','y', + 'a','d','v','i','c','e','h','a','s','n','o','b','a','s','i','s', + 'm','o','r','e','r','e','l','i','a','b','l','e','t','h','a','n', + 'm','y','o','w','n','m','e','a','n','d','e','r','i','n','g','e', + 'x','p','e','r','i','e','n','c','e','I','w','i','l','l','d','i', + 's','p','e','n','s','e','t','h','i','s','a','d','v','i','c','e', + 'n','o','w','E','n','j','o','y','t','h','e','p','o','w','e','r', + 'a','n','d','b','e','a','u','t','y','o','f','y','o','u','r','y', + 'o','u','t','h','O','h','n','e','v','e','r','m','i','n','d','Y', + 'o','u','w','i','l','l','n','o','t','u','n','d','e','r','s','t', + 'a','n','d','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','u', + 'n','t','i','l','t','h','e','y','v','e','f','a','d','e','d','B', + 'u','t','t','r','u','s','t','m','e','i','n','2','0','y','e','a', + 'r','s','y','o','u','l','l','l','o','o','k','b','a','c','k','a', + 't','p','h','o','t','o','s','o','f','y','o','u','r','s','e','l', + 'f','a','n','d','r','e','c','a','l','l','i','n','a','w','a','y', + 'y','o','u','c','a','n','t','g','r','a','s','p','n','o','w','h', + 'o','w','m','u','c','h','p','o','s','s','i','b','i','l','i','t', + 'y','l','a','y','b','e','f','o','r','e','y','o','u','a','n','d', + 'h','o','w','f','a','b','u','l','o','u','s','y','o','u','r','e', + 'a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r','e', + 'n','o','t','a','s','f','a','t','a','s','y','o','u','i','m','a', + 'g','i','n','e','D','o','n','t','w','o','r','r','y','a','b','o', + 'u','t','t','h','e','f','u','t','u','r','e','O','r','w','o','r', + 'r','y','b','u','t','k','n','o','w','t','h','a','t','K','u','r', + 't','V','o','n','n','e','g','u','t','s','C','o','m','m','e','n', + 'c','e','m','e','n','t','A','d','d','r','e','s','s','a','t','M', + 'I','T','L','a','d','i','e','s','a','n','d','g','e','n','t','l', + 'e','m','e','n','o','f','t','h','e','c','l','a','s','s','o','f', + '9','7','W','e','a','r','s','u','n','s','c','r','e','e','n','I', + 'f','I','c','o','u','l','d','o','f','f','e','r','y','o','u','o', + 'n','l','y','o','n','e','t','i','p','f','o','r','t','h','e','f', + 'u','t','u','r','e','s','u','n','s','c','r','e','e','n','w','o', + 'u','l','d','b','e','i','t','T','h','e','l','o','n','g','t','e', + 'r','m','b','e','n','e','f','i','t','s','o','f','s','u','n','s', + 'c','r','e','e','n','h','a','v','e','b','e','e','n','p','r','o', + 'v','e','d','b','y','s','c','i','e','n','t','i','s','t','s','w', + 'h','e','r','e','a','s','t','h','e','r','e','s','t','o','f','m', + 'y','a','d','v','i','c','e','h','a','s','n','o','b','a','s','i', + 's','m','o','r','e','r','e','l','i','a','b','l','e','t','h','a', + 'n','m','y','o','w','n','m','e','a','n','d','e','r','i','n','g', + 'e','x','p','e','r','i','e','n','c','e','I','w','i','l','l','d', + 'i','s','p','e','n','s','e','t','h','i','s','a','d','v','i','c', + 'e','n','o','w','E','n','j','o','y','t','h','e','p','o','w','e', + 'r','a','n','d','b','e','a','u','t','y','o','f','y','o','u','r', + 'y','o','u','t','h','O','h','n','e','v','e','r','m','i','n','d', + 'Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r','s', + 't','a','n','d','t','h','e','p','o','w','e','r','a','n','d','b', + 'e','a','u','t','y','o','f','y','o','u','r','y','o','u','t','h', + 'u','n','t','i','l','t','h','e','y','v','e','f','a','d','e','d', + 'B','u','t','t','r','u','s','t','m','e','i','n','2','0','y','e', + 'a','r','s','y','o','u','l','l','l','o','o','k','b','a','c','k', + 'a','t','p','h','o','t','o','s','o','f','y','o','u','r','s','e', + 'l','f','a','n','d','r','e','c','a','l','l','i','n','a','w','a', + 'y','y','o','u','c','a','n','t','g','r','a','s','p','n','o','w', + 'h','o','w','m','u','c','h','p','o','s','s','i','b','i','l','i', + 't','y','l','a','y','b','e','f','o','r','e','y','o','u','a','n', + 'd','h','o','w','f','a','b','u','l','o','u','s','y','o','u','r', + 'e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a','r', + 'e','n','o','t','a','s','f','a','t','a','s','y','o','u','i','m', + 'a','g','i','n','e','D','o','n','t','w','o','r','r','y','a','b', + 'o','u','t','t','h','e','f','u','t','u','r','e','O','r','w','o', + 'r','r','y','b','u','t','k','n','o','w','t','h','a','t','K','u', + 'r','t','V','o','n','n','e','g','u','t','s','C','o','m','m','e', + 'n','c','e','m','e','n','t','A','d','d','r','e','s','s','a','t', + 'M','I','T','L','a','d','i','e','s','a','n','d','g','e','n','t', + 'l','e','m','e','n','o','f','t','h','e','c','l','a','s','s','o', + 'f','9','7','W','e','a','r','s','u','n','s','c','r','e','e','n', + 'I','f','I','c','o','u','l','d','o','f','f','e','r','y','o','u', + 'o','n','l','y','o','n','e','t','i','p','f','o','r','t','h','e', + 'f','u','t','u','r','e','s','u','n','s','c','r','e','e','n','w', + 'o','u','l','d','b','e','i','t','T','h','e','l','o','n','g','t', + 'e','r','m','b','e','n','e','f','i','t','s','o','f','s','u','n', + 's','c','r','e','e','n','h','a','v','e','b','e','e','n','p','r', + 'o','v','e','d','b','y','s','c','i','e','n','t','i','s','t','s', + 'w','h','e','r','e','a','s','t','h','e','r','e','s','t','o','f', + 'm','y','a','d','v','i','c','e','h','a','s','n','o','b','a','s', + 'i','s','m','o','r','e','r','e','l','i','a','b','l','e','t','h', + 'a','n','m','y','o','w','n','m','e','a','n','d','e','r','i','n', + 'g','e','x','p','e','r','i','e','n','c','e','I','w','i','l','l', + 'd','i','s','p','e','n','s','e','t','h','i','s','a','d','v','i', + 'c','e','n','o','w','E','n','j','o','y','t','h','e','p','o','w', + 'e','r','a','n','d','b','e','a','u','t','y','o','f','y','o','u', + 'r','y','o','u','t','h','O','h','n','e','v','e','r','m','i','n', + 'd','Y','o','u','w','i','l','l','n','o','t','u','n','d','e','r', + 's','t','a','n','d','t','h','e','p','o','w','e','r','a','n','d', + 'b','e','a','u','t','y','o','f','y','o','u','r','y','o','u','t', + 'h','u','n','t','i','l','t','h','e','y','v','e','f','a','d','e', + 'd','B','u','t','t','r','u','s','t','m','e','i','n','2','0','y', + 'e','a','r','s','y','o','u','l','l','l','o','o','k','b','a','c', + 'k','a','t','p','h','o','t','o','s','o','f','y','o','u','r','s', + 'e','l','f','a','n','d','r','e','c','a','l','l','i','n','a','w', + 'a','y','y','o','u','c','a','n','t','g','r','a','s','p','n','o', + 'w','h','o','w','m','u','c','h','p','o','s','s','i','b','i','l', + 'i','t','y','l','a','y','b','e','f','o','r','e','y','o','u','a', + 'n','d','h','o','w','f','a','b','u','l','o','u','s','y','o','u', + 'r','e','a','l','l','y','l','o','o','k','e','d','Y','o','u','a', + 'r','e','n','o','t','a','s','f','a','t','a','s','y','o','u','i', + 'm','a','g','i','n','e','D','o','n','t','w','o','r','r','y','a', + 'b','o','u','t','t','h','e','f','u','t','u','r','e','O','r','w', + 'o','r','r','y','b','u','t','k','n','o','w','t','h','a','t','s', + 'u','n','s','c','r','e','e','n','w','o','u','l','d','b','e','i', + 't','T','h','e','l','o','n','g','t','e','r','m','b','e','n','e', + 'f','i','t','s','o','f','s','u','n','s','c','r','e','e','n','h', + 'a','v','e','b','e','e','n','p','r','o','v','e','d','b','y','s', + 'c','i','e','n','t','i','s','t','s','w','h','e','r','e','a','s', + 't','h','e','r','e','s','t','o','f','m','y','a','d','v','i','c', + 'e','h','a','s','n','o','b','a','s','i','s','m','o','r','e','r', + 'e','l','i','a','b','l','e','t','h','a','n','m','y','o','w','n', + 'm','e','a','n','d','e','r','i','n','g','e','x','p','e','r','i', + 'e','n','c','e','I','w','i','l','l','d','i','s','p','e','n','s', + 'e','t','h','i','s','a','d','v','i','c','e','n','o','w','E','n', + 'j','o','y','t','h','e','p','o','w','e','r','a','n','d','b','e', + 'a','u','t','y','o','f','y','o','u','r','y','o','u','t','h','O', + 'h','n','e','v','e','r','m','i','n','d','Y','o','u','w','i','l', + 'l','n','o','t','u','n','d','e','r','s','t','a','n','d','t','h', + 'e','p','o','w','e','r','a','n','d','b','e','a','u','t','y','o', + 'f','y','o','u','r','y','o','u','t','h','u','n','t','i','l','t', + 'h','e','y','v','e','f','a','d','e','d','B','u','t','t','r','u', + 's','t','m','e','i','n','2','0','y','e','a','r','s','y','o','u', + 'l','l','l','o','o','k','b','a','c','k','a','t','p','h','o','t', + 'o','s','o','f','y','o','u','r','s','e','l','f','a','n','d','r', + 'e','c','a','l','l','i','n','a','w','a','y','y','o','u','c','a', + 'n','t','g','r','a','s','p','n','o','w','h','o','w','m','u','c', + 'h','p','o','s','s','i','b','i','l','i','t','y','l','a','y','b', + 'e','f','o','r','e','y','o','u','a','n','d','h','o','w','f','a', + 'b','u','l','o','u','s','y','o','u','r','e','a','l','l','y','l', + 'o','o','k','e','d','Y','o','u','a','r','e','n','o','t','a','s', + 'f','a','t','a','s','y','o','u','i','m','a','g','i','n','e','D', + 'o','n','t','w','o','r','r','y','a','b','o','u','t','t','h','e', + 'f','u','t','u','r','e','O','r','w','o','r','r','y','b','u','t', + 'k','n','o','w','t','h','a','t','\n' +}; diff --git a/baseline/source/rijndael_enc/rijndael_enc.c b/baseline/source/rijndael_enc/rijndael_enc.c new file mode 100644 index 0000000..f74d595 --- /dev/null +++ b/baseline/source/rijndael_enc/rijndael_enc.c @@ -0,0 +1,238 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: rijndael_enc + + Author: Dr Brian Gladman + + Function: rijndael_enc is an implementation of the AES encryption + algorithm (Rijndael). + + Source: security section of MiBench + + Changes: Add computation of a checksum, refactoring + + License: see below + +*/ + +/* + ----------------------------------------------------------------------- + Copyright (c) 2001 Dr Brian Gladman , Worcester, UK + + TERMS + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + This software is provided 'as is' with no guarantees of correctness or + fitness for purpose. + ----------------------------------------------------------------------- +*/ + +#include "../extra.h" +#include "aes.h" +#include "rijndael_enc_libc.h" + +/* + Global variable definitions +*/ +unsigned char rijndael_enc_key[32]; +int rijndael_enc_key_len; + +extern unsigned char rijndael_enc_data[]; +struct rijndael_enc_FILE rijndael_enc_fin; + +int rijndael_enc_checksum = 0; + +/* + Forward declaration of functions +*/ +void rijndael_enc_init( void ); +int rijndael_enc_return( void ); +void rijndael_enc_fillrand( unsigned char *buf, int len ); +void rijndael_enc_encfile( struct rijndael_enc_FILE *fin, struct aes *ctx ); +void rijndael_enc_main( void ); + +void rijndael_enc_init( void ) +{ + /* create a pseudo-file for the input*/ + rijndael_enc_fin.data = rijndael_enc_data; + rijndael_enc_fin.size = 31369; + rijndael_enc_fin.cur_pos = 0; + + unsigned i; + volatile int x = 0; + rijndael_enc_fin.size ^= x; + _Pragma( "loopbound min 31369 max 31369" ) + for ( i = 0; i < rijndael_enc_fin.size; i++ ) + rijndael_enc_fin.data[i] ^= x; + + /* this is a pointer to the hexadecimal key digits */ + const volatile char *cp = + "1234567890abcdeffedcba09876543211234567890abcdeffedcba0987654321"; + char ch; + int by = 0; + + i = 0; /* this is a count for the input digits processed */ + _Pragma( "loopbound min 64 max 64" ) + while ( i < 64 && *cp ) { /* the maximum key length is 32 bytes and */ + /* hence at most 64 hexadecimal digits */ + ch = rijndael_enc_toupper( *cp++ ); /* process a hexadecimal digit */ + if ( ch >= '0' && ch <= '9' ) + by = ( by << 4 ) + ch - '0'; + else + if ( ch >= 'A' && ch <= 'F' ) + by = ( by << 4 ) + ch - 'A' + 10; + else { /* error if not hexadecimal */ + rijndael_enc_checksum = -2; + return; + } + + /* store a key byte for each pair of hexadecimal digits */ + if ( i++ & 1 ) + rijndael_enc_key[i / 2 - 1] = by & 0xff; + } + + if ( *cp ) { + rijndael_enc_checksum = -3; + return; + } else + if ( i < 32 || ( i & 15 ) ) { + rijndael_enc_checksum = -4; + return; + } + + rijndael_enc_key_len = i / 2; +} + +int rijndael_enc_return( void ) +{ + return ( ( rijndael_enc_checksum == ( int )249509 ) ? 0 : -1 ); +} + +/* A Pseudo Random Number Generator (PRNG) used for the */ +/* Initialisation Vector. The PRNG is George Marsaglia's */ +/* Multiply-With-Carry (MWC) PRNG that concatenates two */ +/* 16-bit MWC generators: */ +/* x(n)=36969 * x(n-1) + carry mod 2^16 */ +/* y(n)=18000 * y(n-1) + carry mod 2^16 */ +/* to produce a combined PRNG with a period of about 2^60. */ + +#define RAND(a,b) (((a = 36969 * (a & 65535) + (a >> 16)) << 16) + (b = 18000 * (b & 65535) + (b >> 16)) ) + +void rijndael_enc_fillrand( unsigned char *buf, int len ) +{ + static unsigned long a[2], mt = 1, count = 4; + static char r[4]; + int i; + + if ( mt ) { + mt = 0; + a[0] = 0xeaf3; + a[1] = 0x35fe; + } + + _Pragma( "loopbound min 1 max 16" ) + for ( i = 0; i < len; ++i ) { + if ( count == 4 ) { + *( unsigned long * )r = RAND( a[0], a[1] ); + count = 0; + } + + buf[i] = r[count++]; + } +} + +void rijndael_enc_encfile( struct rijndael_enc_FILE *fin, struct aes *ctx ) +{ + unsigned char inbuf[16], outbuf[16]; + long int flen; + unsigned long i = 0, l = 0; + + rijndael_enc_fillrand( outbuf, + 16 ); /* set an IV for CBC mode */ + flen = fin->size; + + rijndael_enc_fillrand( inbuf, + 1 ); /* make top 4 bits of a byte random */ + l = 15; /* and store the length of the last */ + /* block in the lower 4 bits */ + inbuf[0] = ( ( char )flen & 15 ) | ( inbuf[0] & ~15 ); + + /* TODO: this is necessarily an input-dependent loop bound */ + _Pragma( "loopbound min 1961 max 1961" ) + while ( !rijndael_enc_feof( + fin ) ) { /* loop to encrypt the input file */ + /* input 1st 16 bytes to buf[1..16] */ + i = rijndael_enc_fread( inbuf + 16 - l, 1, l, fin ); /* on 1st round byte[0] */ + /* is the length code */ + if ( i < l ) break; /* if end of the input file reached */ + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor in previous cipher text */ + inbuf[i] ^= outbuf[i]; + + rijndael_enc_encrypt( inbuf, outbuf, + ctx ); /* and do the encryption */ + + rijndael_enc_checksum += outbuf[15]; + + /* in all but first round read 16 */ + l = 16; /* bytes into the buffer */ + } + + /* except for files of length less than two blocks we now have one */ + /* byte from the previous block and 'i' bytes from the current one */ + /* to encrypt and 15 - i empty buffer positions. For files of less */ + /* than two blocks (0 or 1) we have i + 1 bytes and 14 - i empty */ + /* buffer position to set to zero since the 'count' byte is extra */ + + if ( l == 15 ) /* adjust for extra byte in the */ + ++i; /* in the first block */ + + if ( i ) { /* if bytes remain to be output */ + _Pragma( "loopbound min 6 max 6" ) + while ( i < 16 ) /* clear empty buffer positions */ + inbuf[i++] = 0; + + _Pragma( "loopbound min 16 max 16" ) + for ( i = 0; i < 16; ++i ) /* xor in previous cipher text */ + inbuf[i] ^= outbuf[i]; + + rijndael_enc_encrypt( inbuf, outbuf, ctx ); /* encrypt and output it */ + + rijndael_enc_checksum += outbuf[15]; + } +} + +void _Pragma( "entrypoint" ) rijndael_enc_main( void ) +{ + struct aes ctx[1]; + + /* encryption in Cipher Block Chaining mode */ + rijndael_enc_set_key( rijndael_enc_key, rijndael_enc_key_len, enc, ctx ); + rijndael_enc_encfile( &rijndael_enc_fin, ctx ); +} + +int main( int argc, char** argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete= 'a' ) && ( c <= 'z' ) ) + return c - 'a' + 'A'; + return c; +} + +unsigned long rijndael_enc_fread( void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_read = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 10 max 16" ) + while ( i < stream->cur_pos + number_of_chars_to_read ) + ( ( unsigned char * )ptr )[i2++] = stream->data[i++]; + stream->cur_pos += number_of_chars_to_read; + return number_of_chars_to_read; +} + +unsigned long rijndael_enc_fwrite( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ) +{ + unsigned i = stream->cur_pos, i2 = 0; + unsigned long number_of_chars_to_write = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 0 max 0" ) + while ( i < stream->cur_pos + number_of_chars_to_write ) + stream->data[i++] = ( ( unsigned char * )ptr )[i2++]; + stream->cur_pos += number_of_chars_to_write; + return number_of_chars_to_write; +} + +int rijndael_enc_fseek( struct rijndael_enc_FILE *stream, long int offset, + Origin origin ) +{ + if ( origin == RIJNDAEL_ENC_SEEK_SET ) { + stream->cur_pos = offset; + return 0; + } else + if ( origin == RIJNDAEL_ENC_SEEK_CUR ) { + stream->cur_pos += offset; + return 0; + } else + if ( origin == RIJNDAEL_ENC_SEEK_END ) { + stream->cur_pos = stream->size + offset; + return 0; + } + return -1; +} + +int rijndael_enc_fgetpos( struct rijndael_enc_FILE *stream, + unsigned *position ) +{ + *position = stream->cur_pos; + return 0; +} + +int rijndael_enc_feof( struct rijndael_enc_FILE *stream ) +{ + return stream->cur_pos == stream->size ? 1 : 0; +} diff --git a/baseline/source/rijndael_enc/rijndael_enc_libc.h b/baseline/source/rijndael_enc/rijndael_enc_libc.h new file mode 100644 index 0000000..6a01397 --- /dev/null +++ b/baseline/source/rijndael_enc/rijndael_enc_libc.h @@ -0,0 +1,24 @@ +#ifndef RIJNDAEL_ENC_LIBC_H +#define RIJNDAEL_ENC_LIBC_H + +int rijndael_enc_toupper ( int c ); + +enum _Origin_ { RIJNDAEL_ENC_SEEK_SET, RIJNDAEL_ENC_SEEK_CUR, RIJNDAEL_ENC_SEEK_END }; +typedef enum _Origin_ Origin; +struct rijndael_enc_FILE { + unsigned char *data; + unsigned long size; + unsigned cur_pos; +}; + +unsigned long rijndael_enc_fread ( void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ); +unsigned long rijndael_enc_fwrite ( const void *ptr, unsigned long size, + unsigned long count, struct rijndael_enc_FILE *stream ); +int rijndael_enc_fseek ( struct rijndael_enc_FILE *stream, long int offset, + Origin origin ); +int rijndael_enc_fgetpos( struct rijndael_enc_FILE *stream, + unsigned *position ); +int rijndael_enc_feof ( struct rijndael_enc_FILE *stream ); + +#endif // RIJNDAEL_ENC_LIBC_H diff --git a/baseline/source/statemate/ChangeLog.txt b/baseline/source/statemate/ChangeLog.txt new file mode 100644 index 0000000..bce75dc --- /dev/null +++ b/baseline/source/statemate/ChangeLog.txt @@ -0,0 +1,60 @@ +File: statemate.c +Original provenience: Mälardalen benchmark suite, + http://www.mrtc.mdh.se/projects/wcet/benchmarks.html + +2016-02-02: +- Removed original header comment, replaced by TACLeBench header. +- Removed macro '#define float int' and replaced each 'float' by 'int' (8 in + total) +- Removed unused macro + - #define entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_copy_IDX 1 +- Removed unused variables + - int FH_TUERMODUL_CTRL__N_copy; + - int BLOCK_ERKENNUNG_CTRL__I_EIN_MAX_copy; + - int BLOCK_ERKENNUNG_CTRL__N_copy; + - char FH_TUERMODUL_CTRL__FT; + - char FH_TUERMODUL__COM_OPEN; + - char FH_TUERMODUL__COM_CLOSE; + - char FH_DU__S_FH_TMBFAUFCAN_copy; + - char FH_DU__S_FH_TMBFZUCAN_copy; +- Moved around all the following so that they are in the given order just after +the header + - macro definitions + - forward declarations of fuctions + - declarations of global variables +- Reordered functions in source code: initialization-related functions first, + followed by algorithm core functions, followed by main functions +- Added a new main function that first calls init function then the old main + function sans init +- Annotated statemate_main() as the entry point of the analysis +- Removed seemingly unnecessary empty lines +- Changed remaining floating number literals, all being used for time related + comparisons, to integer literals by multiplying them by 1000 so that the + code is totally floating number free. E.g: + changed 'time - sc_FH_TUERMODUL_CTRL_2375_2 >= 0.5f' + to 'time - sc_FH_TUERMODUL_CTRL_2375_2 >= 500' + Info: All time related variables were already converted to 'unsigned long' +- Applied code formatting according to the following rules + - Lines shall not be wider than 80 characters; whenever possible, appropriate + line breaks shall be inserted to keep lines below 80 characters + - Indentation is done using whitespaces only, no tabs. Code is indented by + two whitespaces + - Two empty lines are put between any two functions + - In non-empty lists or index expressions, opening '(' and '[' are followed by + one whitespace, closing ')' and ']' are preceded by one whitespace + - In comma- or colon-separated argument lists, one whitespace is put after + each comma/colon + - Names of functions and global variables all start with a benchmark-specific + prefix (here: statemate_) followed by lowercase letter + - For pointer types, one whitespace is put before the '*' + - Operators within expressions shall be preceded and followed by one + whitespace + - Code of then- and else-parts of if-then-else statements shall be put in + separate lines, not in the same lines as the if-condition or the keyword + "else" + - Opening braces '{' denoting the beginning of code for some if-else or loop + body shall be put at the end of the same line where the keywords "if", + "else", "for", "while" etc. occur + + 2016-10-10: + - added statemate_return() function diff --git a/baseline/source/statemate/statemate.c b/baseline/source/statemate/statemate.c new file mode 100644 index 0000000..379366a --- /dev/null +++ b/baseline/source/statemate/statemate.c @@ -0,0 +1,1286 @@ +/* + + This program is part of the TACLeBench benchmark suite. + Version V 2.0 + + Name: statemate + + Author: Friedhelm Stappert, C-LAB, Paderborn, Germany + + Function: This code was automatically generated by + the STAtechart Real-time-Code generator STARC + which was developed at C-LAB. + + The original StateChart specifies an experimental + car window lift control. + + Source: MRTC + http://www.mrtc.mdh.se/projects/wcet/wcet_bench/statemate/statemate.c + + Changes: no major functional changes + + License: may be used, modified, and re-distributed freely + +*/ + +/* + Macro definitions +*/ + +#include "../extra.h" + +#define SYS_bit_get(a,b) (a)[(b)] +#define SYS_bit_clr(a,b) (a)[(b)] = 0 +#define SYS_bit_set(a,b) (a)[(b)] = 1 +#define SYS_bit_cpy(a1,i1,a2,i2) (a1)[(i1)] = (a2)[(i2)] + +#define active_KINDERSICHERUNG_CTRL_IDX 10 +#define active_KINDERSICHERUNG_CTRL_copy_IDX 11 +#define active_KINDERSICHERUNG_CTRL_old_IDX 12 +#define active_FH_TUERMODUL_CTRL_IDX 13 +#define active_FH_TUERMODUL_CTRL_copy_IDX 14 +#define active_FH_TUERMODUL_CTRL_old_IDX 15 +#define active_EINKLEMMSCHUTZ_CTRL_IDX 16 +#define active_EINKLEMMSCHUTZ_CTRL_copy_IDX 17 +#define active_EINKLEMMSCHUTZ_CTRL_old_IDX 18 +#define active_BLOCK_ERKENNUNG_CTRL_IDX 19 +#define active_BLOCK_ERKENNUNG_CTRL_copy_IDX 20 +#define active_BLOCK_ERKENNUNG_CTRL_old_IDX 21 +#define entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX 0 + +#define entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX 4 +#define entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX 5 +#define exited_BEREIT_FH_TUERMODUL_CTRL_IDX 6 +#define exited_BEREIT_FH_TUERMODUL_CTRL_copy_IDX 7 + +#define FH_TUERMODUL_CTRL__END_REVERS_IDX 22 +#define FH_TUERMODUL_CTRL__END_REVERS_copy_IDX 23 +#define FH_TUERMODUL__EINKLEMMUNG_IDX 24 + + +/* + Forward declaration of functions +*/ + +void statemate_init( void ); +void statemate_interface( void ); +void statemate_generic_KINDERSICHERUNG_CTRL( void ); +void statemate_generic_FH_TUERMODUL_CTRL( void ); +void statemate_generic_EINKLEMMSCHUTZ_CTRL( void ); +void statemate_generic_BLOCK_ERKENNUNG_CTRL( void ); +void statemate_FH_DU( void ); +void statemate_main( void ); +int statemate_return ( void ); + + +/* + Declaration of global variables +*/ + +static char statemate_bitlist[64]; +unsigned long +statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy; +unsigned long +statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL; +unsigned long statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_2375_2; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_2352_1; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_2329_1; +int statemate_FH_TUERMODUL_CTRL__N; +int statemate_FH_TUERMODUL_CTRL__N_old; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_1781_10; +unsigned long statemate_sc_FH_TUERMODUL_CTRL_1739_10; +int statemate_FH_TUERMODUL__POSITION; +int statemate_FH_TUERMODUL__I_EIN; +int statemate_FH_TUERMODUL__I_EIN_old; +int statemate_FH_DU__MFH; +int statemate_FH_DU__MFH_copy; +int statemate_FH_DU__POSITION; +int statemate_FH_DU__I_EIN; +int statemate_FH_DU__I_EIN_old; +int statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX; +int statemate_BLOCK_ERKENNUNG_CTRL__N; +int statemate_BLOCK_ERKENNUNG_CTRL__N_old; +char statemate_FH_TUERMODUL_CTRL__INREVERS2; +char statemate_FH_TUERMODUL_CTRL__INREVERS2_copy; +char statemate_FH_TUERMODUL_CTRL__INREVERS1; +char statemate_FH_TUERMODUL_CTRL__INREVERS1_copy; +char statemate_FH_TUERMODUL__SFHZ_ZENTRAL; +char statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old; +char statemate_FH_TUERMODUL__SFHZ_MEC; +char statemate_FH_TUERMODUL__SFHZ_MEC_old; +char statemate_FH_TUERMODUL__SFHA_ZENTRAL; +char statemate_FH_TUERMODUL__SFHA_ZENTRAL_old; +char statemate_FH_TUERMODUL__SFHA_MEC; +char statemate_FH_TUERMODUL__SFHA_MEC_old; +char statemate_FH_TUERMODUL__KL_50; +char statemate_FH_TUERMODUL__BLOCK; +char statemate_FH_TUERMODUL__BLOCK_copy; +char statemate_FH_TUERMODUL__BLOCK_old; +char statemate_FH_TUERMODUL__FT; +char statemate_FH_TUERMODUL__SFHZ; +char statemate_FH_TUERMODUL__SFHZ_copy; +char statemate_FH_TUERMODUL__SFHZ_old; +char statemate_FH_TUERMODUL__SFHA; +char statemate_FH_TUERMODUL__SFHA_copy; +char statemate_FH_TUERMODUL__SFHA_old; +char statemate_FH_TUERMODUL__MFHZ; +char statemate_FH_TUERMODUL__MFHZ_copy; +char statemate_FH_TUERMODUL__MFHZ_old; +char statemate_FH_TUERMODUL__MFHA; +char statemate_FH_TUERMODUL__MFHA_copy; +char statemate_FH_TUERMODUL__MFHA_old; +char statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; +char statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old; +char statemate_FH_DU__KL_50; +char statemate_FH_DU__S_FH_FTZU; +char statemate_FH_DU__S_FH_FTAUF; +char statemate_FH_DU__FT; +char statemate_FH_DU__EKS_LEISTE_AKTIV; +char statemate_FH_DU__EKS_LEISTE_AKTIV_old; +char statemate_FH_DU__S_FH_TMBFAUFCAN; +char statemate_FH_DU__S_FH_TMBFAUFCAN_old; +char statemate_FH_DU__S_FH_TMBFZUCAN; +char statemate_FH_DU__S_FH_TMBFZUCAN_old; +char statemate_FH_DU__S_FH_TMBFZUDISC; +char statemate_FH_DU__S_FH_TMBFZUDISC_old; +char statemate_FH_DU__S_FH_TMBFAUFDISC; +char statemate_FH_DU__S_FH_TMBFAUFDISC_old; +char statemate_FH_DU__S_FH_ZUDISC; +char statemate_FH_DU__S_FH_AUFDISC; +char statemate_FH_DU__DOOR_ID; +char statemate_FH_DU__BLOCK; +char statemate_FH_DU__BLOCK_copy; +char statemate_FH_DU__BLOCK_old; +char statemate_FH_DU__MFHZ; +char statemate_FH_DU__MFHZ_copy; +char statemate_FH_DU__MFHZ_old; +char statemate_FH_DU__MFHA; +char statemate_FH_DU__MFHA_copy; +char statemate_FH_DU__MFHA_old; + +unsigned long statemate_time; +char statemate_stable; +char statemate_step; + +char +statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state; /** 2 bits **/ +char +statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state; /** 1 bits **/ +char statemate_MEC_KINDERSICHERUNG_CTRL_next_state; /** 1 bits **/ +char +statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state; /** 2 bits **/ +char statemate_B_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char statemate_A_FH_TUERMODUL_CTRL_next_state; /** 1 bits **/ +char +statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state; /** 1 bits **/ +char +statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state; /** 2 bits **/ +char +statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state; /** 2 bits **/ +char +statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state; /** 2 bits **/ +char +statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state; /** 2 bits **/ +char +statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state; /** 2 bits **/ + + +/* + Initialization-related functions +*/ + +void statemate_init( void ) +{ + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + = 0; + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + = 0; + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL = 0; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 0; + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 0; + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 0; + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 0; + statemate_B_FH_TUERMODUL_CTRL_next_state = 0; + statemate_A_FH_TUERMODUL_CTRL_next_state = 0; + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 0; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 0; + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 0; + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 0; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 0; + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 0; + + statemate_interface(); +} /** statemate_init **/ + + +void statemate_interface( void ) +{ + if ( SYS_bit_get( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ) ) + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL = statemate_time; + if ( SYS_bit_get( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ) || + SYS_bit_get( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_IDX ) ) + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + = statemate_time; + if ( ( statemate_sc_FH_TUERMODUL_CTRL_2375_2 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_2375_2 >= 500 ) ) { + statemate_FH_TUERMODUL__MFHA_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2375_2 = 0; + } + if ( ( statemate_sc_FH_TUERMODUL_CTRL_2352_1 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_2352_1 >= 500 ) ) { + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2352_1 = 0; + } + if ( ( statemate_sc_FH_TUERMODUL_CTRL_2329_1 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_2329_1 >= 500 ) ) { + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2329_1 = 0; + } + if ( ( statemate_sc_FH_TUERMODUL_CTRL_1781_10 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_1781_10 >= 500 ) ) + statemate_sc_FH_TUERMODUL_CTRL_1781_10 = 0; + + if ( ( statemate_sc_FH_TUERMODUL_CTRL_1739_10 != 0 ) && + ( statemate_time - statemate_sc_FH_TUERMODUL_CTRL_1739_10 >= 500 ) ) + statemate_sc_FH_TUERMODUL_CTRL_1739_10 = 0; + + if ( ( SYS_bit_get( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ) || + statemate_BLOCK_ERKENNUNG_CTRL__N != statemate_BLOCK_ERKENNUNG_CTRL__N_old ) ) + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + = statemate_time; +} /** statemate_interface **/ + + +/* + Algorithm core functions +*/ + +void statemate_generic_KINDERSICHERUNG_CTRL( void ) +{ + if ( SYS_bit_get( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX ) ) { + switch ( statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state ) { + case 1: { /** state ZENTRAL in chart KINDERSICHERUNG_CTRL **/ + if ( !( statemate_FH_TUERMODUL__SFHA_ZENTRAL || + statemate_FH_TUERMODUL__SFHZ_ZENTRAL ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 0; + break; + } + switch ( statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state ) { + case 1: { /** state IN_ZENTRAL in chart KINDERSICHERUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHA_ZENTRAL && + !( statemate_FH_TUERMODUL__SFHA_ZENTRAL_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + !( statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHA_ZENTRAL ) && + statemate_FH_TUERMODUL__SFHA_ZENTRAL_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHZ_ZENTRAL ) && + statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + + statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + break; + } + } /** switch statemate_ZENTRAL_KINDERSICHERUNG_CTRL_next_state **/ + break; + } + case 2: { /** state MEC in chart KINDERSICHERUNG_CTRL **/ + if ( !( statemate_FH_TUERMODUL__SFHA_MEC || + statemate_FH_TUERMODUL__SFHZ_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 0; + break; + } + switch ( statemate_MEC_KINDERSICHERUNG_CTRL_next_state ) { + case 1: { /** state INMEC in chart KINDERSICHERUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHA_MEC && + !( statemate_FH_TUERMODUL__SFHA_MEC_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_MEC && + !( statemate_FH_TUERMODUL__SFHZ_MEC_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHA_MEC ) && + statemate_FH_TUERMODUL__SFHA_MEC_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 0; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHZ_MEC ) && + statemate_FH_TUERMODUL__SFHZ_MEC_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 0; + + statemate_MEC_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + break; + } + } /** switch statemate_MEC_KINDERSICHERUNG_CTRL_next_state **/ + break; + } + case 3: { /** state WAITING in chart KINDERSICHERUNG_CTRL **/ + if ( ( !statemate_FH_TUERMODUL__KL_50 ) && ( statemate_FH_TUERMODUL__SFHZ_MEC && + statemate_FH_TUERMODUL__SFHA_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 2; + break; + } + if ( ( !statemate_FH_TUERMODUL__KL_50 ) && ( statemate_FH_TUERMODUL__SFHZ_MEC && + !statemate_FH_TUERMODUL__SFHA_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 2; + break; + } + if ( ( !statemate_FH_TUERMODUL__KL_50 ) && + ( !statemate_FH_TUERMODUL__SFHZ_MEC && + statemate_FH_TUERMODUL__SFHA_MEC ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 2; + break; + } + if ( ( !statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + statemate_FH_TUERMODUL__SFHA_ZENTRAL && + !statemate_FH_TUERMODUL__KL_50 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + statemate_FH_TUERMODUL__SFHA_ZENTRAL ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHA_copy = 1; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ_ZENTRAL && + !statemate_FH_TUERMODUL__SFHA_ZENTRAL && + !statemate_FH_TUERMODUL__KL_50 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__SFHZ_copy = 1; + + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + break; + } + } /** switch statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state **/ + } +} + + +void statemate_generic_FH_TUERMODUL_CTRL( void ) +{ + if ( !SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX ) && + SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_old_IDX ) && + !SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX ) ) { + SYS_bit_clr( statemate_bitlist, entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_clr( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_IDX ); + } + if ( SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX ) ) { + if ( !SYS_bit_get( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX ) ) + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + SYS_bit_clr( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) ) { + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + } + SYS_bit_clr( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + switch ( statemate_B_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state ZAEHLER_WHSP_ZU_HOCH in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL_CTRL__N == 59 && + !( statemate_FH_TUERMODUL_CTRL__N_old == 59 ) ) ) { + statemate_stable = 0; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 3; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + break; + } + case 2: { /** state NICHT_INITIALISIERT in chart FH_TUERMODUL_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL__BLOCK && + !( statemate_FH_TUERMODUL__BLOCK_old ) ) ) && + ( ( statemate_FH_TUERMODUL__MFHZ ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2329_1 = statemate_time; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 3; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state ) { + case 1: { /** state SCHLIESSEN in chart NICHT_INITIALISIERT **/ + if ( !( statemate_FH_TUERMODUL__SFHZ ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + break; + } + case 2: { /** state OEFFNEN in chart NICHT_INITIALISIERT **/ + if ( !( statemate_FH_TUERMODUL__SFHA ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + break; + } + case 3: { /** state BEREIT in chart NICHT_INITIALISIERT **/ + if ( ( statemate_FH_TUERMODUL__SFHA ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 1; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 2; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHZ ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 1; + + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + } /** switch statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state **/ + break; + } + case 3: { /** state INITIALISIERT in chart FH_TUERMODUL_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL_CTRL__N > 60 && + !( statemate_FH_TUERMODUL_CTRL__N_old > 60 ) ) ) && + ( ( !( statemate_FH_TUERMODUL_CTRL__INREVERS1 || + statemate_FH_TUERMODUL_CTRL__INREVERS2 ) ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + if ( ( ( statemate_FH_TUERMODUL__BLOCK && + !( statemate_FH_TUERMODUL__BLOCK_old ) ) ) && + ( ( statemate_FH_TUERMODUL__MFHA ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2375_2 = statemate_time; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + if ( ( ( statemate_FH_TUERMODUL__BLOCK && + !( statemate_FH_TUERMODUL__BLOCK_old ) ) ) && + ( ( statemate_FH_TUERMODUL__MFHZ ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_sc_FH_TUERMODUL_CTRL_2352_1 = statemate_time; + + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + statemate_NICHT_INITIALISIERT_NICHT_INITIALISIERT_next_state = 3; + break; + } + switch ( statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state OEFFNEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__POSITION >= 405 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state TIPP_OEFFNEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHZ && + !( statemate_FH_TUERMODUL__SFHZ_old ) ) || + ( statemate_FH_TUERMODUL__SFHA && !( statemate_FH_TUERMODUL__SFHA_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 0; + break; + } + break; + } + case 2: { /** state MAN_OEFFNEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHZ && + !( statemate_FH_TUERMODUL__SFHZ_old ) ) ) { + statemate_stable = 0; + + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + if ( ( !( statemate_FH_TUERMODUL__SFHA ) && + statemate_FH_TUERMODUL__SFHA_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 0; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 2; + break; + } + } /** switch statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + case 2: { /** state SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__POSITION <= 0 ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state TIPP_SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_FH_TUERMODUL__SFHA && + !( statemate_FH_TUERMODUL__SFHA_old ) ) || + ( statemate_FH_TUERMODUL__SFHZ && !( statemate_FH_TUERMODUL__SFHZ_old ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state REVERSIEREN2 in chart FH_TUERMODUL_CTRL **/ + SYS_bit_clr( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 1; + statemate_FH_TUERMODUL_CTRL__INREVERS2_copy = 0; + + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + break; + } + break; + } + case 2: { /** state TIPP_SCHLIESSEN1 in chart FH_TUERMODUL_CTRL **/ + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__INREVERS2_copy = 1; + + SYS_bit_set( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_clr( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_sc_FH_TUERMODUL_CTRL_1781_10 = statemate_time; + statemate_FH_TUERMODUL__MFHA_copy = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + break; + } + } /** switch statemate_TIPP_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + case 2: { /** state MANUELL_SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( ( !( statemate_FH_TUERMODUL__SFHZ ) && + statemate_FH_TUERMODUL__SFHZ_old ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + switch ( statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state REVERSIEREN1 in chart FH_TUERMODUL_CTRL **/ + SYS_bit_clr( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__INREVERS1_copy = 0; + + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_FH_TUERMODUL__MFHA_copy = 0; + + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + break; + } + case 2: { /** state MAN_SCHLIESSEN in chart FH_TUERMODUL_CTRL **/ + if ( SYS_bit_get( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHZ_copy = 0; + statemate_FH_TUERMODUL_CTRL__INREVERS1_copy = 1; + + SYS_bit_set( statemate_bitlist, FH_TUERMODUL_CTRL__END_REVERS_copy_IDX ); + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_clr( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + + statemate_sc_FH_TUERMODUL_CTRL_1739_10 = statemate_time; + statemate_FH_TUERMODUL__MFHA_copy = 1; + break; + } + if ( ( statemate_FH_TUERMODUL__SFHA && + !( statemate_FH_TUERMODUL__SFHA_old ) ) ) { + statemate_stable = 0; + + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 1; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 0; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + } /** switch statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + } /** switch statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state **/ + break; + } + case 3: { /** state BEREIT in chart FH_TUERMODUL_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL__SFHZ && + !( statemate_FH_TUERMODUL__SFHZ_old ) ) ) && + ( ( statemate_FH_TUERMODUL__POSITION > 0 ) ) ) { + statemate_stable = 0; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 2; + statemate_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + statemate_MANUELL_SCHLIESSEN_FH_TUERMODUL_CTRL_next_state = 2; + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + statemate_FH_TUERMODUL__MFHZ_copy = 1; + break; + } + if ( ( ( statemate_FH_TUERMODUL__SFHA && + !( statemate_FH_TUERMODUL__SFHA_old ) ) ) && + ( ( statemate_FH_TUERMODUL__POSITION < 405 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__MFHA_copy = 1; + + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 1; + statemate_OEFFNEN_FH_TUERMODUL_CTRL_next_state = 2; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state = 3; + break; + } + } /** switch statemate_INITIALISIERT_FH_TUERMODUL_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + break; + } + } /** switch statemate_B_FH_TUERMODUL_CTRL_next_state **/ + switch ( statemate_A_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state WIEDERHOLSPERRE in chart FH_TUERMODUL_CTRL **/ + SYS_bit_clr( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + if ( ( statemate_step == 1 && + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + != 0 + && ( statemate_time - + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRLexited_BEREIT_FH_TUERMODUL_CTRL + == + 1 ) ) && ( ( statemate_FH_TUERMODUL__MFHZ || + statemate_FH_TUERMODUL__MFHA ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__N = statemate_FH_TUERMODUL_CTRL__N + 1; + + statemate_A_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + switch ( statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state ) { + case 1: { /** state WDHSP in chart FH_TUERMODUL_CTRL **/ + if ( ( statemate_step == 1 && + statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL != 0 && + ( statemate_time - statemate_tm_entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL == + 3 ) ) && + ( ( ( !( statemate_FH_TUERMODUL__MFHZ || statemate_FH_TUERMODUL__MFHA ) ) && + statemate_FH_TUERMODUL_CTRL__N > 0 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__N = statemate_FH_TUERMODUL_CTRL__N - 1; + + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + } /** switch statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_FH_TUERMODUL_CTRL__N = 0; + statemate_A_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + break; + } + } /** switch statemate_A_FH_TUERMODUL_CTRL_next_state **/ + SYS_bit_cpy( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX, + statemate_bitlist, entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_copy_IDX, + statemate_bitlist, + exited_BEREIT_FH_TUERMODUL_CTRL_IDX ); + } +} + + +void statemate_generic_EINKLEMMSCHUTZ_CTRL( void ) +{ + if ( SYS_bit_get( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_IDX ) ) { + switch ( statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state ) { + case 1: { /** state NORMALBETRIEB in chart EINKLEMMSCHUTZ_CTRL **/ + if ( ( ( statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV && + !( statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old ) ) ) && + ( ( !( statemate_FH_TUERMODUL__SFHZ && + statemate_FH_TUERMODUL__SFHA ) ) ) ) { + statemate_stable = 0; + + SYS_bit_set( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ); + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 2; + break; + } + break; + } + case 2: { /** state EINKLEMMUNG in chart EINKLEMMSCHUTZ_CTRL **/ + SYS_bit_clr( statemate_bitlist, FH_TUERMODUL__EINKLEMMUNG_IDX ); + if ( ( !( statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV ) && + statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old ) ) { + statemate_stable = 0; + + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 1; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 1; + break; + } + } /** switch statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state **/ + } +} + + +void statemate_generic_BLOCK_ERKENNUNG_CTRL( void ) +{ + if ( !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) && + SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_old_IDX ) && + !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ) ) + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + if ( SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) ) { + switch ( statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state ) { + case 1: { /** state KEINE_BEWEGUNG in chart BLOCK_ERKENNUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__I_EIN != statemate_FH_TUERMODUL__I_EIN_old ) && + ( ( statemate_FH_TUERMODUL__I_EIN > 0 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__BLOCK_copy = 0; + + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 2; + statemate_BLOCK_ERKENNUNG_CTRL__N = 0; + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX = 2; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 3; + SYS_bit_set( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + break; + } + break; + } + case 2: { /** state BEWEGUNG in chart BLOCK_ERKENNUNG_CTRL **/ + if ( ( !( statemate_FH_TUERMODUL__MFHA ) && + statemate_FH_TUERMODUL__MFHA_old ) || + ( !( statemate_FH_TUERMODUL__MFHZ ) && statemate_FH_TUERMODUL__MFHZ_old ) ) { + statemate_stable = 0; + + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 0; + break; + } + switch ( statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state ) { + case 1: { /** state FENSTER_BLOCKIERT in chart BLOCK_ERKENNUNG_CTRL **/ + break; + } + case 2: { /** state FENSTER_BEWEGT_SICH in chart BLOCK_ERKENNUNG_CTRL **/ + if ( ( statemate_FH_TUERMODUL__I_EIN > + ( statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX - 2 ) ) ) { + statemate_stable = 0; + statemate_FH_TUERMODUL__BLOCK_copy = 1; + + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 1; + break; + } + break; + } + case 3: { /** state EINSCHALTSTROM_MESSEN in chart BLOCK_ERKENNUNG_CTRL **/ + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + if ( ( statemate_BLOCK_ERKENNUNG_CTRL__N == 11 && + !( statemate_BLOCK_ERKENNUNG_CTRL__N_old == 11 ) ) ) { + statemate_stable = 0; + + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 2; + break; + } + /** static reactions: **/ + if ( statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state == 3 ) { + if ( statemate_step == 1 && + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + != 0 && ( statemate_time - + statemate_tm_entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRLch_BLOCK_ERKENNUNG_CTRL__N_copy + == 2 ) ) { + statemate_BLOCK_ERKENNUNG_CTRL__N = statemate_BLOCK_ERKENNUNG_CTRL__N + 1; + if ( ( statemate_FH_TUERMODUL__I_EIN > + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX ) ) + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX = statemate_FH_TUERMODUL__I_EIN; + + } + } + /** end static reactions **/ + break; + } + default: { + statemate_stable = 0; + statemate_BLOCK_ERKENNUNG_CTRL__N = 0; + statemate_BLOCK_ERKENNUNG_CTRL__I_EIN_MAX = 2; + statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state = 3; + SYS_bit_set( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + break; + } + } /** switch statemate_BEWEGUNG_BLOCK_ERKENNUNG_CTRL_next_state **/ + break; + } + default: { + statemate_stable = 0; + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + break; + } + } /** switch statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state **/ + } +} + + +void statemate_FH_DU( void ) +{ + statemate_time = 1; /**SYS_get_clock()**/ + statemate_stable = 0; + statemate_step = 0; + // patched for wcet: replacing while statement by for + //while (!statemate_stable) + int i; + _Pragma( "loopbound min 100 max 100" ) + for ( i = 0; i < 100; i++ ) { + statemate_stable = 1; + statemate_step++; + { + switch ( statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state ) { + case 1: { /** state SCHLIESSEN in chart FH_STEUERUNG_DUMMY **/ + if ( ( !( statemate_FH_DU__MFHZ ) && statemate_FH_DU__MFHZ_old ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = 0; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 2; + break; + } + break; + } + case 2: { /** state BEREIT in chart FH_STEUERUNG_DUMMY **/ + if ( ( statemate_FH_DU__MFHZ && !( statemate_FH_DU__MFHZ_old ) ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = -100; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 1; + break; + } + if ( ( statemate_FH_DU__MFHA && !( statemate_FH_DU__MFHA_old ) ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = 100; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 3; + break; + } + break; + } + case 3: { /** state OEFFNEN in chart FH_STEUERUNG_DUMMY **/ + if ( ( !( statemate_FH_DU__MFHA ) && statemate_FH_DU__MFHA_old ) ) { + statemate_stable = 0; + statemate_FH_DU__MFH = 0; + + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 2; + break; + } + break; + } + default: { + statemate_stable = 0; + statemate_FH_DU__MFH = 0; + statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state = 2; + break; + } + } /** switch statemate_FH_STEUERUNG_DUMMY_FH_STEUERUNG_DUMMY_next_state **/ + } + { + { + if ( !SYS_bit_get( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX ) ) + statemate_KINDERSICHERUNG_CTRL_KINDERSICHERUNG_CTRL_next_state = 3; + SYS_bit_clr( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_IDX ) ) + statemate_EINKLEMMSCHUTZ_CTRL_EINKLEMMSCHUTZ_CTRL_next_state = 1; + SYS_bit_clr( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX ) ) { + SYS_bit_clr( statemate_bitlist, + entered_EINSCHALTSTROM_MESSEN_BLOCK_ERKENNUNG_CTRL_IDX ); + statemate_BLOCK_ERKENNUNG_CTRL_BLOCK_ERKENNUNG_CTRL_next_state = 1; + } + SYS_bit_clr( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + if ( !SYS_bit_get( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX ) ) { + SYS_bit_clr( statemate_bitlist, entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_clr( statemate_bitlist, exited_BEREIT_FH_TUERMODUL_CTRL_IDX ); + statemate_B_FH_TUERMODUL_CTRL_next_state = 2; + statemate_FH_TUERMODUL_CTRL__N = 0; + statemate_A_FH_TUERMODUL_CTRL_next_state = 1; + SYS_bit_set( statemate_bitlist, + entered_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_copy_IDX ); + statemate_WIEDERHOLSPERRE_FH_TUERMODUL_CTRL_next_state = 1; + } + SYS_bit_clr( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX ); + SYS_bit_set( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX ); + /** static reactions: **/ + if ( statemate_FH_DU__S_FH_TMBFZUCAN != statemate_FH_DU__S_FH_TMBFZUCAN_old ) { + if ( ( !statemate_FH_DU__DOOR_ID ) ) + statemate_FH_DU__S_FH_FTZU = statemate_FH_DU__S_FH_TMBFZUCAN; + + } + if ( statemate_FH_DU__S_FH_TMBFZUDISC != + statemate_FH_DU__S_FH_TMBFZUDISC_old ) { + if ( statemate_FH_DU__DOOR_ID ) + statemate_FH_DU__S_FH_TMBFZUCAN = statemate_FH_DU__S_FH_TMBFZUDISC; + + } + if ( statemate_FH_DU__S_FH_TMBFAUFCAN != + statemate_FH_DU__S_FH_TMBFAUFCAN_old ) { + if ( ( !statemate_FH_DU__DOOR_ID ) ) + statemate_FH_DU__S_FH_FTAUF = statemate_FH_DU__S_FH_TMBFAUFCAN; + + } + if ( statemate_FH_DU__S_FH_TMBFAUFDISC != + statemate_FH_DU__S_FH_TMBFAUFDISC_old ) { + if ( statemate_FH_DU__DOOR_ID ) + statemate_FH_DU__S_FH_TMBFAUFCAN = statemate_FH_DU__S_FH_TMBFAUFDISC; + + } + /** end static reactions **/ + } + } + SYS_bit_cpy( statemate_bitlist, active_KINDERSICHERUNG_CTRL_IDX, + statemate_bitlist, + active_KINDERSICHERUNG_CTRL_old_IDX ); + SYS_bit_cpy( statemate_bitlist, active_FH_TUERMODUL_CTRL_IDX, statemate_bitlist, + active_FH_TUERMODUL_CTRL_old_IDX ); + SYS_bit_cpy( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_IDX, + statemate_bitlist, + active_EINKLEMMSCHUTZ_CTRL_old_IDX ); + SYS_bit_cpy( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_IDX, + statemate_bitlist, + active_BLOCK_ERKENNUNG_CTRL_old_IDX ); + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_KINDERSICHERUNG_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_FH_TUERMODUL_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_EINKLEMMSCHUTZ_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + statemate_FH_TUERMODUL__SFHA_MEC = statemate_FH_DU__S_FH_AUFDISC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL = statemate_FH_DU__S_FH_FTAUF; + statemate_FH_TUERMODUL__SFHZ_MEC = statemate_FH_DU__S_FH_ZUDISC; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL = statemate_FH_DU__S_FH_FTZU; + + statemate_generic_BLOCK_ERKENNUNG_CTRL(); + + statemate_FH_DU__MFHA = statemate_FH_TUERMODUL__MFHA; + statemate_FH_DU__MFHZ = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_DU__I_EIN = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__EKS_LEISTE_AKTIV = statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__POSITION = statemate_FH_TUERMODUL__POSITION; + statemate_FH_DU__FT = statemate_FH_TUERMODUL__FT; + statemate_FH_DU__S_FH_AUFDISC = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_DU__S_FH_FTAUF = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_DU__S_FH_ZUDISC = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_DU__S_FH_FTZU = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_DU__KL_50 = statemate_FH_TUERMODUL__KL_50; + statemate_FH_DU__BLOCK = statemate_FH_TUERMODUL__BLOCK; + + SYS_bit_cpy( statemate_bitlist, active_KINDERSICHERUNG_CTRL_copy_IDX, + statemate_bitlist, + active_KINDERSICHERUNG_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, active_FH_TUERMODUL_CTRL_copy_IDX, + statemate_bitlist, + active_FH_TUERMODUL_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, active_EINKLEMMSCHUTZ_CTRL_copy_IDX, + statemate_bitlist, + active_EINKLEMMSCHUTZ_CTRL_IDX ); + SYS_bit_cpy( statemate_bitlist, active_BLOCK_ERKENNUNG_CTRL_copy_IDX, + statemate_bitlist, + active_BLOCK_ERKENNUNG_CTRL_IDX ); + statemate_FH_TUERMODUL_CTRL__N_old = statemate_FH_TUERMODUL_CTRL__N; + statemate_FH_TUERMODUL__I_EIN_old = statemate_FH_TUERMODUL__I_EIN; + statemate_FH_DU__MFH = statemate_FH_DU__MFH_copy; + statemate_FH_DU__I_EIN_old = statemate_FH_DU__I_EIN; + statemate_BLOCK_ERKENNUNG_CTRL__N_old = statemate_BLOCK_ERKENNUNG_CTRL__N; + statemate_FH_TUERMODUL__SFHZ_ZENTRAL_old = statemate_FH_TUERMODUL__SFHZ_ZENTRAL; + statemate_FH_TUERMODUL__SFHZ_MEC_old = statemate_FH_TUERMODUL__SFHZ_MEC; + statemate_FH_TUERMODUL__SFHA_ZENTRAL_old = statemate_FH_TUERMODUL__SFHA_ZENTRAL; + statemate_FH_TUERMODUL__SFHA_MEC_old = statemate_FH_TUERMODUL__SFHA_MEC; + statemate_FH_TUERMODUL__BLOCK = statemate_FH_TUERMODUL__BLOCK_copy; + statemate_FH_TUERMODUL__BLOCK_old = statemate_FH_TUERMODUL__BLOCK; + statemate_FH_TUERMODUL__SFHZ = statemate_FH_TUERMODUL__SFHZ_copy; + statemate_FH_TUERMODUL__SFHZ_old = statemate_FH_TUERMODUL__SFHZ; + statemate_FH_TUERMODUL__SFHA = statemate_FH_TUERMODUL__SFHA_copy; + statemate_FH_TUERMODUL__SFHA_old = statemate_FH_TUERMODUL__SFHA; + statemate_FH_TUERMODUL__MFHZ = statemate_FH_TUERMODUL__MFHZ_copy; + statemate_FH_TUERMODUL__MFHZ_old = statemate_FH_TUERMODUL__MFHZ; + statemate_FH_TUERMODUL__MFHA = statemate_FH_TUERMODUL__MFHA_copy; + statemate_FH_TUERMODUL__MFHA_old = statemate_FH_TUERMODUL__MFHA; + statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV_old = + statemate_FH_TUERMODUL__EKS_LEISTE_AKTIV; + statemate_FH_DU__EKS_LEISTE_AKTIV_old = statemate_FH_DU__EKS_LEISTE_AKTIV; + statemate_FH_DU__S_FH_TMBFAUFCAN_old = statemate_FH_DU__S_FH_TMBFAUFCAN; + statemate_FH_DU__S_FH_TMBFZUCAN_old = statemate_FH_DU__S_FH_TMBFZUCAN; + statemate_FH_DU__S_FH_TMBFZUDISC_old = statemate_FH_DU__S_FH_TMBFZUDISC; + statemate_FH_DU__S_FH_TMBFAUFDISC_old = statemate_FH_DU__S_FH_TMBFAUFDISC; + statemate_FH_DU__BLOCK = statemate_FH_DU__BLOCK_copy; + statemate_FH_DU__BLOCK_old = statemate_FH_DU__BLOCK; + statemate_FH_DU__MFHZ = statemate_FH_DU__MFHZ_copy; + statemate_FH_DU__MFHZ_old = statemate_FH_DU__MFHZ; + statemate_FH_DU__MFHA = statemate_FH_DU__MFHA_copy; + statemate_FH_DU__MFHA_old = statemate_FH_DU__MFHA; + + } /** while(!statemate_stable) **/ + +} /** statemate_FH_DU **/ + + +/* + Main functions +*/ + +int statemate_return() +{ + unsigned long int checksum = 0; + int index; + for ( index=63 ; index>=0 ; index-- ){ + checksum += (unsigned long) (statemate_bitlist[index] << index); + } + return(checksum == 18446744073709551614ul); +} + +void _Pragma ( "entrypoint" ) statemate_main( void ) +{ + statemate_FH_DU(); +} + + +int main ( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsComplete +//#include + +/* A representation of a double as a union. */ +union ieee754_double +{ + double d; + + /* This is the IEEE 754 double-precision format. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct { + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + } ieee_nan; +}; + +/* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +/* #if __FLOAT_WORD_ORDER == BIG_ENDIAN */ +/* #warning USING Big Endian float word order */ +/* typedef union */ +/* { */ +/* double value; */ +/* struct */ +/* { */ +/* u_int16_t msw; */ +/* u_int16_t lsw; */ +/* } parts; */ +/* } ieeeDoubleShapeType; */ + +/* #endif */ + +/* #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN */ +/* #warning USING Little Endian float word order */ + +typedef union +{ + double value; + struct + { + u_int16_t lsw; + u_int16_t msw; + } parts; +} ieeeDoubleShapeType; + +/* #endif */ + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +{ \ + ieeeDoubleShapeType ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +{ \ + ieeeDoubleShapeType gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +{ \ + ieeeDoubleShapeType iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +{ \ + ieeeDoubleShapeType sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + u_int32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +{ \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +{ \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} + + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/baseline/source/susan/susan.c b/baseline/source/susan/susan.c new file mode 100644 index 0000000..fb990b1 --- /dev/null +++ b/baseline/source/susan/susan.c @@ -0,0 +1,2014 @@ +/**********************************************************************\ + + SUSAN Version 2l by Stephen Smith + Oxford Centre for Functional Magnetic Resonance Imaging of the Brain, + Department of Clinical Neurology, Oxford University, Oxford, UK + (Previously in Computer Vision and Image Processing Group - now + Computer Vision and Electro Optics Group - DERA Chertsey, UK) + Email: steve@fmrib.ox.ac.uk + WWW: http://www.fmrib.ox.ac.uk/~steve + + (C) Crown Copyright (1995-1999), Defence Evaluation and Research Agency, + Farnborough, Hampshire, GU14 6TD, UK + DERA WWW site: + http://www.dera.gov.uk/ + DERA Computer Vision and Electro Optics Group WWW site: + http://www.dera.gov.uk/imageprocessing/dera/group_home.html + DERA Computer Vision and Electro Optics Group point of contact: + Dr. John Savage, jtsavage@dera.gov.uk, +44 1344 633203 + + A UK patent has been granted: "Method for digitally processing + images to determine the position of edges and/or corners therein for + guidance of unmanned vehicle", UK Patent 2272285. Proprietor: + Secretary of State for Defence, UK. 15 January 1997 + + This code is issued for research purposes only and remains the + property of the UK Secretary of State for Defence. This code must + not be passed on without this header information being kept + intact. This code must not be sold. + +\**********************************************************************/ + +/**********************************************************************\ + + SUSAN Version 2l + SUSAN = Smallest Univalue Segment Assimilating Nucleus + + Email: steve@fmrib.ox.ac.uk + WWW: http://www.fmrib.ox.ac.uk/~steve + + Related paper: + @article{Smith97, + author = "Smith, S.M. and Brady, J.M.", + title = "{SUSAN} - A New Approach to Low Level Image Processing", + journal = "Int. Journal of Computer Vision", + pages = "45--78", + volume = "23", + number = "1", + month = "May", + year = 1997} + + To be registered for automatic (bug) updates of SUSAN, send an email. + + Compile with: + gcc -O4 -o susan susan2l.c -lm + + See following section for different machine information. Please + report any bugs (and fixes). There are a few optional changes that + can be made in the "defines" section which follows shortly. + + Usage: type "susan" to get usage. Only PGM format files can be input + and output. Utilities such as the netpbm package and XV can be used + to convert to and from other formats. Any size of image can be + processed. + + This code is written using an emacs folding mode, making moving + around the different sections very easy. This is why there are + various marks within comments and why comments are indented. + + + SUSAN QUICK: + + This version of the SUSAN corner finder does not do all the + false-corner suppression and thus is faster and produced some false + positives, particularly on strong edges. However, because there are + less stages involving thresholds etc., the corners that are + correctly reported are usually more stable than those reported with + the full algorithm. Thus I recommend at least TRYING this algorithm + for applications where stability is important, e.g., tracking. + + THRESHOLDS: + + There are two thresholds which can be set at run-time. These are the + brightness threshold (t) and the distance threshold (d). + + SPATIAL CONTROL: d + + In SUSAN smoothing d controls the size of the Gaussian mask; its + default is 4.0. Increasing d gives more smoothing. In edge finding, + a fixed flat mask is used, either 37 pixels arranged in a "circle" + (default), or a 3 by 3 mask which gives finer detail. In corner + finding, only the larger 37 pixel mask is used; d is not + variable. In smoothing, the flat 3 by 3 mask can be used instead of + a larger Gaussian mask; this gives low smoothing and fast operation. + + BRIGHTNESS CONTROL: t + + In all three algorithms, t can be varied (default=20); this is the + main threshold to be varied. It determines the maximum difference in + greylevels between two pixels which allows them to be considered + part of the same "region" in the image. Thus it can be reduced to + give more edges or corners, i.e. to be more sensitive, and vice + versa. In smoothing, reducing t gives less smoothing, and vice + versa. Set t=10 for the test image available from the SUSAN web + page. + + ITERATIONS: + + With SUSAN smoothing, more smoothing can also be obtained by + iterating the algorithm several times. This has a different effect + from varying d or t. + + FIXED MASKS: + + 37 pixel mask: ooo 3 by 3 mask: ooo + ooooo ooo + ooooooo ooo + ooooooo + ooooooo + ooooo + ooo + + CORNER ATTRIBUTES dx, dy and I + (Only read this if you are interested in the C implementation or in + using corner attributes, e.g., for corner matching) + + Corners reported in the corner list have attributes associated with + them as well as positions. This is useful, for example, when + attempting to match corners from one image to another, as these + attributes can often be fairly unchanged between images. The + attributes are dx, dy and I. I is the value of image brightness at + the position of the corner. In the case of susan_corners_quick, dx + and dy are the first order derivatives (differentials) of the image + brightness in the x and y directions respectively, at the position + of the corner. In the case of normal susan corner finding, dx and dy + are scaled versions of the position of the centre of gravity of the + USAN with respect to the centre pixel (nucleus). + + BRIGHTNESS FUNCTION LUT IMPLEMENTATION: + (Only read this if you are interested in the C implementation) + + The SUSAN brightness function is implemented as a LUT + (Look-Up-Table) for speed. The resulting pointer-based code is a + little hard to follow, so here is a brief explanation. In + setup_brightness_lut() the LUT is setup. This mallocs enough space + for *bp and then repositions the pointer to the centre of the + malloced space. The SUSAN function e^-(x^6) or e^-(x^2) is + calculated and converted to a uchar in the range 0-100, for all + possible image brightness differences (including negative + ones). Thus bp[23] is the output for a brightness difference of 23 + greylevels. In the SUSAN algorithms this LUT is used as follows: + + p=in + (i-3)*x_size + j - 1; + p points to the first image pixel in the circular mask surrounding + point (x,y). + + cp=bp + in[i*x_size+j]; + cp points to a position in the LUT corresponding to the brightness + of the centre pixel (x,y). + + now for every pixel within the mask surrounding (x,y), + n+=*(cp-*p++); + the brightness difference function is found by moving the cp pointer + down by an amount equal to the value of the pixel pointed to by p, + thus subtracting the two brightness values and performing the + exponential function. This value is added to n, the running USAN + area. + + in SUSAN smoothing, the variable height mask is implemented by + multiplying the above by the moving mask pointer, reset for each new + centre pixel. + tmp = *dpt++ * *(cp-brightness); + +\**********************************************************************/ + +/**********************************************************************\ + + Success has been reported with the following: + + MACHINE OS COMPILER + + Sun 4.1.4 bundled C, gcc + + Next + + SGI IRIX SGI cc + + DEC Unix V3.2+ + + IBM RISC AIX gcc + + PC Borland 5.0 + + PC Linux gcc-2.6.3 + + PC Win32 Visual C++ 4.0 (Console Application) + + PC Win95 Visual C++ 5.0 (Console Application) + Thanks to Niu Yongsheng : + Use the FOPENB option below + + PC DOS djgpp gnu C + Thanks to Mark Pettovello : + Use the FOPENB option below + + HP HP-UX bundled cc + Thanks to Brian Dixon : + in ksh: + export CCOPTS="-Aa -D_HPUX_SOURCE | -lM" + cc -O3 -o susan susan2l.c + +\**********************************************************************/ + +/**********************************************************************\ + + SUSAN Version 2l, 12/2/99 + Changed GNUDOS option to FOPENB. + (Thanks to Niu Yongsheng .) + Took out redundant "sq=sq/2;". + + SUSAN Version 2k, 19/8/98: + In corner finding: + Changed if(yyx_size) etc. tests in smoothing. + Added a couple of free() calls for cgx and cgy. + (Thanks to geoffb@ucs.ed.ac.uk - Geoff Browitt.) + + SUSAN Version 2i, 21/7/97: + Added information about corner attributes. + + SUSAN Version 2h, 16/12/96: + Added principle (initial enhancement) option. + + SUSAN Version 2g, 2/7/96: + Minor superficial changes to code. + + SUSAN Version 2f, 16/1/96: + Added GNUDOS option (now called FOPENB; see options below). + + SUSAN Version 2e, 9/1/96: + Added -b option. + Fixed 1 pixel horizontal offset error for drawing edges. + + SUSAN Version 2d, 27/11/95: + Fixed loading of certain PGM files in get_image (again!) + + SUSAN Version 2c, 22/11/95: + Fixed loading of certain PGM files in get_image. + (Thanks to qu@San-Jose.ate.slb.com - Gongyuan Qu.) + + SUSAN Version 2b, 9/11/95: + removed "z==" error in edges routines. + + SUSAN Version 2a, 6/11/95: + Removed a few unnecessary variable declarations. + Added different machine information. + Changed "header" in get_image to char. + + SUSAN Version 2, 1/11/95: first combined version able to take any + image sizes. + + SUSAN "Versions 1", circa 1992: the various SUSAN algorithms were + developed during my doctorate within different programs and for + fixed image sizes. The algorithms themselves are virtually unaltered + between "versions 1" and the combined program, version 2. + +\**********************************************************************/ + +#include "../extra.h" +#include "wcclibm.h" +#include "wccfile.h" +#include "wccmalloc.h" + +#define EXP_A 184 +#define EXP_C 16249 + +float susan_expf(float y) +{ + union + { + float d; + struct + { +#ifdef LITTLE_ENDIAN + short j, i; +#else + short i, j; +#endif + } n; + } eco; + eco.n.i = EXP_A*(y) + (EXP_C); + eco.n.j = 0; + return eco.d; +} + +float susan_sqrtf(float val) +{ + float x = val/10; + + float dx; + + float diff; + float min_tol = 0.00001f; + + int i, flag; + + + flag = 0; + if (val == 0 ) x = 0; + else { + for (i=1;i<20;i++) + { + if (!flag) { + dx = (val - (x*x)) / (2.0f * x); + x = x + dx; + diff = val - (x*x); + if (fabs(diff) <= min_tol) flag = 1; + } + } + } + return (x); +} + +/* ********** Optional settings */ + +typedef int TOTAL_TYPE; + +#define SEVEN_SUPP /* size for non-max corner suppression; SEVEN_SUPP or FIVE_SUPP */ +#define MAX_CORNERS 15000 /* max corners per frame */ + +#define FTOI(a) ( (a) < 0 ? ((int)(a-0.5)) : ((int)(a+0.5)) ) +#define abs(a) ( (a) < 0 ? -a : a ) +typedef unsigned char uchar; +typedef struct {int x,y,info, dx, dy, I;} corner_rep; +typedef corner_rep CORNER_LIST[MAX_CORNERS]; + +extern char susan_input[7292]; +struct wccFILE susan_file; +float susan_dt; +int susan_bt; +int susan_principle_conf; +int susan_thin_post_proc; +int susan_three_by_three; +int susan_drawing_mode; +int susan_susan_quick; +int susan_max_no_corners; +int susan_max_no_edges; + +int susan_getint( struct wccFILE *fd ) +{ + int c, i; + char dummy[10000]; + + c = susan_wccfgetc(fd); + _Pragma( "loopbound min 1 max 4" ) + while (1) { /* find next integer */ + if (c=='#') /* if we're at a comment, read to end of line */ + susan_wccfgets(dummy,9000,fd); + if (c==EOFX) { + /* "Image is not binary PGM." */ + } + if (c>='0' && c<='9') + break; /* found what we were looking for */ + c = susan_wccfgetc(fd); + } + + /* we're at the start of a number, continue until we hit a non-number */ + i = 0; + _Pragma( "loopbound min 2 max 3" ) + while (1) { + i = (i*10) + (c - '0'); + c = susan_wccfgetc(fd); + if (c==EOFX) return (i); + if (c<'0' || c>'9') break; + } + + return (i); +} + + +void susan_get_image( struct wccFILE *fd, + unsigned char **in, int *x_size, int *y_size ) +{ + char header [100]; + + susan_wccfseek( fd, 0, WCCSEEK_SET ); + + /* {{{ read header */ + + header[0]=susan_wccfgetc( fd ); + header[1]=susan_wccfgetc( fd ); + if(!(header[0]=='P' && header[1]=='5')) { + /* "Image does not have binary PGM header." */ + } + + *x_size = susan_getint(fd); + *y_size = susan_getint(fd); + // dummy read + susan_getint(fd); + +/* }}} */ + + *in = (uchar *) susan_wccmalloc(*x_size * *y_size); + + if (susan_wccfread(*in,1,*x_size * *y_size,fd) == 0) { + /* "Image is wrong size.\n" */ + } +} + + +void susan_put_image( int x_size, int y_size ) +{ + int i; + _Pragma( "loopbound min 7220 max 7220" ) + for ( i = 0; i < x_size*y_size; i++ ) { + ; + } +} + + +void susan_int_to_uchar( char *r, uchar *in, int size ) +{ + int i, max_r=r[0], min_r=r[0]; + + _Pragma( "loopbound min 0 max 0" ) + for (i=0; i max_r ) + max_r=r[i]; + if ( r[i] < min_r ) + min_r=r[i]; + } + + if (max_r == min_r) { + /* Should not occur in TACLeBench. */ + _Pragma( "loopbound min 0 max 0" ) + for (i=0; ip[l+1]) { + tmp=p[l]; + p[l]=p[l+1]; + p[l+1]=tmp; + } + } + } + + return( (p[3]+p[4]) / 2 ); +} + + +/* this enlarges "in" so that borders can be dealt with easily */ +void susan_enlarge( uchar **in, uchar *tmp_image, + int *x_size, int *y_size, int border ) +{ + int i, j; + + _Pragma( "loopbound min 95 max 95" ) + for(i=0; i<*y_size; i++) { /* copy *in into tmp_image */ + susan_wccmemcpy( tmp_image+(i+border)*(*x_size+2*border)+border, + *in+i* *x_size, *x_size); + } + + _Pragma( "loopbound min 7 max 7" ) + for(i=0; i15 ) { + /* "Distance_thresh too big for integer arithmetic." */ + // Either reduce it to <=15 or recompile with variable "total" + // as a float: see top "defines" section. + } + + if ( (2*mask_size+1>x_size) || (2*mask_size+1>y_size) ) { + /* "Mask size too big for image." */ + } + + tmp_image = (uchar *)susan_wccmalloc( (x_size+mask_size*2) * (y_size+mask_size*2) ); + susan_enlarge(&in,tmp_image,&x_size,&y_size,mask_size); + + if (three_by_three==0) { + /* large Gaussian masks */ + /* {{{ setup distance lut */ + + n_max = (mask_size*2) + 1; + + increment = x_size - n_max; + + dp = (unsigned char *)susan_wccmalloc(n_max*n_max); + dpt = dp; + temp = -(dt*dt); + + _Pragma( "loopbound min 15 max 15" ) + for(i=-mask_size; i<=mask_size; i++) { + _Pragma( "loopbound min 15 max 15" ) + for(j=-mask_size; j<=mask_size; j++) { + x = (int) (100.0 * susan_expf( ((float)((i*i)+(j*j))) / temp )); + *dpt++ = (unsigned char)x; + } + } + + /* {{{ main section */ + + _Pragma( "loopbound min 95 max 95" ) + for (i=mask_size;im) { m=l[y+y+y+x]; a=y; b=x; } + + if (m>0) { + if (mid[i*x_size+j]<4) + mid[(i+a-1)*x_size+j+b-1] = 4; + else + mid[(i+a-1)*x_size+j+b-1] = mid[i*x_size+j]+1; + if ( (a+a+b) < 3 ) { /* need to jump back in image */ + i+=a-1; + j+=b-2; + if (i<4) i=4; + if (j<4) j=4; + } + } + } + + /* {{{ n==2 */ + + if (n==2) { + /* put in a bit here to straighten edges */ + b00 = mid[(i-1)*x_size+j-1]<8; /* corners of 3x3 */ + b02 = mid[(i-1)*x_size+j+1]<8; + b20 = mid[(i+1)*x_size+j-1]<8; + b22 = mid[(i+1)*x_size+j+1]<8; + if ( ((b00+b02+b20+b22)==2) && ((b00|b22)&(b02|b20))) { + /* case: move a point back into line. + e.g. X O X CAN become X X X + O X O O O O + O O O O O O */ + if (b00) { + if (b02) { x=0; y=-1; } + else { x=-1; y=0; } + } else { + if (b02) { x=1; y=0; } + else { x=0; y=1; } + } + if (((float)r[(i+y)*x_size+j+x]/(float)centre) > 0.7) { + if ( ( (x==0) && (mid[(i+(2*y))*x_size+j]>7) && (mid[(i+(2*y))*x_size+j-1]>7) && (mid[(i+(2*y))*x_size+j+1]>7) ) || + ( (y==0) && (mid[(i)*x_size+j+(2*x)]>7) && (mid[(i+1)*x_size+j+(2*x)]>7) && (mid[(i-1)*x_size+j+(2*x)]>7) ) ) { + mid[(i)*x_size+j]=100; + mid[(i+y)*x_size+j+x]=3; /* no jumping needed */ + } + } + } else { + b01 = mid[(i-1)*x_size+j ]<8; + b12 = mid[(i )*x_size+j+1]<8; + b21 = mid[(i+1)*x_size+j ]<8; + b10 = mid[(i )*x_size+j-1]<8; + /* {{{ right angle ends - not currently used */ + +#ifdef IGNORETHIS + if ( (b00&b01)|(b00&b10)|(b02&b01)|(b02&b12)|(b20&b10)|(b20&b21)|(b22&b21)|(b22&b12) ) { + /* case; right angle ends. clean up. + e.g.; X X O CAN become X X O + O X O O O O + O O O O O O */ + if ( ((b01)&(mid[(i-2)*x_size+j-1]>7)&(mid[(i-2)*x_size+j]>7)&(mid[(i-2)*x_size+j+1]>7)& + ((b00&((2*r[(i-1)*x_size+j+1])>centre))|(b02&((2*r[(i-1)*x_size+j-1])>centre)))) | + ((b10)&(mid[(i-1)*x_size+j-2]>7)&(mid[(i)*x_size+j-2]>7)&(mid[(i+1)*x_size+j-2]>7)& + ((b00&((2*r[(i+1)*x_size+j-1])>centre))|(b20&((2*r[(i-1)*x_size+j-1])>centre)))) | + ((b12)&(mid[(i-1)*x_size+j+2]>7)&(mid[(i)*x_size+j+2]>7)&(mid[(i+1)*x_size+j+2]>7)& + ((b02&((2*r[(i+1)*x_size+j+1])>centre))|(b22&((2*r[(i-1)*x_size+j+1])>centre)))) | + ((b21)&(mid[(i+2)*x_size+j-1]>7)&(mid[(i+2)*x_size+j]>7)&(mid[(i+2)*x_size+j+1]>7)& + ((b20&((2*r[(i+1)*x_size+j+1])>centre))|(b22&((2*r[(i+1)*x_size+j-1])>centre)))) ) { + mid[(i)*x_size+j]=100; + if (b10&b20) j-=2; + if (b00|b01|b02) { i--; j-=2; } + } + } +#endif + + if ( ((b01+b12+b21+b10)==2) && ((b10|b12)&(b01|b21)) && + ((b01&((mid[(i-2)*x_size+j-1]<8)|(mid[(i-2)*x_size+j+1]<8)))|(b10&((mid[(i-1)*x_size+j-2]<8)|(mid[(i+1)*x_size+j-2]<8)))| + (b12&((mid[(i-1)*x_size+j+2]<8)|(mid[(i+1)*x_size+j+2]<8)))|(b21&((mid[(i+2)*x_size+j-1]<8)|(mid[(i+2)*x_size+j+1]<8)))) ) { + /* case; clears odd right angles. + e.g.; O O O becomes O O O + X X O X O O + O X O O X O */ + mid[(i)*x_size+j]=100; + i--; /* jump back */ + j-=2; + if (i<4) i=4; + if (j<4) j=4; + } + } + } + + /* {{{ n>2 the thinning is done here without breaking connectivity */ + + if (n>2) { + b01 = mid[(i-1)*x_size+j ]<8; + b12 = mid[(i )*x_size+j+1]<8; + b21 = mid[(i+1)*x_size+j ]<8; + b10 = mid[(i )*x_size+j-1]<8; + if((b01+b12+b21+b10)>1) { + b00 = mid[(i-1)*x_size+j-1]<8; + b02 = mid[(i-1)*x_size+j+1]<8; + b20 = mid[(i+1)*x_size+j-1]<8; + b22 = mid[(i+1)*x_size+j+1]<8; + p1 = b00 | b01; + p2 = b02 | b12; + p3 = b22 | b21; + p4 = b20 | b10; + + if( ((p1 + p2 + p3 + p4) - ((b01 & p2)+(b12 & p3)+(b21 & p4)+(b10 & p1))) < 2) { + mid[(i)*x_size+j]=100; + i--; + j-=2; + if (i<4) i=4; + if (j<4) j=4; + } + } + } + } + } + } +} + + +void susan_edges( uchar *in, char *r, uchar *mid, uchar *bp, + int max_no, int x_size, int y_size ) +{ + float z; + int do_symmetry, i, j, m, n, a, b, x, y, w; + uchar c,*p,*cp; + + susan_wccmemset(r,0,x_size * y_size); + + _Pragma( "loopbound min 89 max 89" ) + for (i=3;i0) { + m=r[i*x_size+j]; + n=max_no - m; + cp=bp + in[i*x_size+j]; + + if (n>600) { + p=in + (i-3)*x_size + j - 1; + x=0;y=0; + + c=*(cp-*p++);x-=c;y-=3*c; + c=*(cp-*p++);y-=3*c; + c=*(cp-*p);x+=c;y-=3*c; + p+=x_size-3; + + c=*(cp-*p++);x-=2*c;y-=2*c; + c=*(cp-*p++);x-=c;y-=2*c; + c=*(cp-*p++);y-=2*c; + c=*(cp-*p++);x+=c;y-=2*c; + c=*(cp-*p);x+=2*c;y-=2*c; + p+=x_size-5; + + c=*(cp-*p++);x-=3*c;y-=c; + c=*(cp-*p++);x-=2*c;y-=c; + c=*(cp-*p++);x-=c;y-=c; + c=*(cp-*p++);y-=c; + c=*(cp-*p++);x+=c;y-=c; + c=*(cp-*p++);x+=2*c;y-=c; + c=*(cp-*p);x+=3*c;y-=c; + p+=x_size-6; + + c=*(cp-*p++);x-=3*c; + c=*(cp-*p++);x-=2*c; + c=*(cp-*p);x-=c; + p+=2; + c=*(cp-*p++);x+=c; + c=*(cp-*p++);x+=2*c; + c=*(cp-*p);x+=3*c; + p+=x_size-6; + + c=*(cp-*p++);x-=3*c;y+=c; + c=*(cp-*p++);x-=2*c;y+=c; + c=*(cp-*p++);x-=c;y+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p++);x+=c;y+=c; + c=*(cp-*p++);x+=2*c;y+=c; + c=*(cp-*p);x+=3*c;y+=c; + p+=x_size-5; + + c=*(cp-*p++);x-=2*c;y+=2*c; + c=*(cp-*p++);x-=c;y+=2*c; + c=*(cp-*p++);y+=2*c; + c=*(cp-*p++);x+=c;y+=2*c; + c=*(cp-*p);x+=2*c;y+=2*c; + p+=x_size-3; + + c=*(cp-*p++);x-=c;y+=3*c; + c=*(cp-*p++);y+=3*c; + c=*(cp-*p);x+=c;y+=3*c; + + z = susan_sqrtf((float)((x*x) + (y*y))); + if (z > (0.9*(float)n)) { /* 0.5 */ + do_symmetry=0; + if (x==0) + z=1000000.0; + else + z=((float)y) / ((float)x); + if (z < 0) { z=-z; w=-1; } + else w=1; + if (z < 0.5) { /* vert_edge */ a=0; b=1; } + else { if (z > 2.0) { /* hor_edge */ a=1; b=0; } + else { /* diag_edge */ if (w>0) { a=1; b=1; } + else { a=-1; b=1; }}} + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) && + (m > r[(i+(2*a))*x_size+j+(2*b)]) && (m >= r[(i-(2*a))*x_size+j-(2*b)]) ) + mid[i*x_size+j] = 1; + } else { + do_symmetry=1; + } + } else { + do_symmetry=1; + } + + if (do_symmetry==1) { + p=in + (i-3)*x_size + j - 1; + x=0; y=0; w=0; + + /* | \ + y -x- w + | \ */ + + c=*(cp-*p++);x+=c;y+=9*c;w+=3*c; + c=*(cp-*p++);y+=9*c; + c=*(cp-*p);x+=c;y+=9*c;w-=3*c; + p+=x_size-3; + + c=*(cp-*p++);x+=4*c;y+=4*c;w+=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w+=2*c; + c=*(cp-*p++);y+=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w-=2*c; + c=*(cp-*p);x+=4*c;y+=4*c;w-=4*c; + p+=x_size-5; + + c=*(cp-*p++);x+=9*c;y+=c;w+=3*c; + c=*(cp-*p++);x+=4*c;y+=c;w+=2*c; + c=*(cp-*p++);x+=c;y+=c;w+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p++);x+=c;y+=c;w-=c; + c=*(cp-*p++);x+=4*c;y+=c;w-=2*c; + c=*(cp-*p);x+=9*c;y+=c;w-=3*c; + p+=x_size-6; + + c=*(cp-*p++);x+=9*c; + c=*(cp-*p++);x+=4*c; + c=*(cp-*p);x+=c; + p+=2; + c=*(cp-*p++);x+=c; + c=*(cp-*p++);x+=4*c; + c=*(cp-*p);x+=9*c; + p+=x_size-6; + + c=*(cp-*p++);x+=9*c;y+=c;w-=3*c; + c=*(cp-*p++);x+=4*c;y+=c;w-=2*c; + c=*(cp-*p++);x+=c;y+=c;w-=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p++);x+=c;y+=c;w+=c; + c=*(cp-*p++);x+=4*c;y+=c;w+=2*c; + c=*(cp-*p);x+=9*c;y+=c;w+=3*c; + p+=x_size-5; + + c=*(cp-*p++);x+=4*c;y+=4*c;w-=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w-=2*c; + c=*(cp-*p++);y+=4*c; + c=*(cp-*p++);x+=c;y+=4*c;w+=2*c; + c=*(cp-*p);x+=4*c;y+=4*c;w+=4*c; + p+=x_size-3; + + c=*(cp-*p++);x+=c;y+=9*c;w-=3*c; + c=*(cp-*p++);y+=9*c; + c=*(cp-*p);x+=c;y+=9*c;w+=3*c; + + if (y==0) + z = 1000000.0; + else + z = ((float)x) / ((float)y); + if (z < 0.5) { /* vertical */ a=0; b=1; } + else { if (z > 2.0) { /* horizontal */ a=1; b=0; } + else { /* diagonal */ if (w>0) { a=-1; b=1; } + else { a=1; b=1; }}} + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) && + (m > r[(i+(2*a))*x_size+j+(2*b)]) && (m >= r[(i-(2*a))*x_size+j-(2*b)]) ) + mid[i*x_size+j] = 2; + } + } + } + } +} + + +void susan_edges_small( uchar *in, char *r, uchar *mid, uchar *bp, + int max_no, int x_size, int y_size ) +{ + float z; + int do_symmetry, i, j, m, n, a, b, x, y, w; + uchar c,*p,*cp; + + susan_wccmemset(r,0,x_size * y_size); + + _Pragma( "loopbound min 0 max 0" ) + for (i=1;i0) { + m=r[i*x_size+j]; + n=max_no - m; + cp=bp + in[i*x_size+j]; + + if (n>250) { + p=in + (i-1)*x_size + j - 1; + x=0;y=0; + + c=*(cp-*p++);x-=c;y-=c; + c=*(cp-*p++);y-=c; + c=*(cp-*p);x+=c;y-=c; + p+=x_size-2; + + c=*(cp-*p);x-=c; + p+=2; + c=*(cp-*p);x+=c; + p+=x_size-2; + + c=*(cp-*p++);x-=c;y+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p);x+=c;y+=c; + + z = susan_sqrtf((float)((x*x) + (y*y))); + if (z > (0.4*(float)n)) { /* 0.6 */ + do_symmetry=0; + if (x==0) + z=1000000.0; + else + z=((float)y) / ((float)x); + if (z < 0) { z=-z; w=-1; } + else w=1; + if (z < 0.5) { /* vert_edge */ a=0; b=1; } + else { if (z > 2.0) { /* hor_edge */ a=1; b=0; } + else { /* diag_edge */ if (w>0) { a=1; b=1; } + else { a=-1; b=1; } + } + } + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) ) { + mid[i*x_size+j] = 1; + } + } else { + do_symmetry=1; + } + } else { + do_symmetry=1; + } + + if (do_symmetry==1) { + p=in + (i-1)*x_size + j - 1; + x=0; y=0; w=0; + + /* | \ + y -x- w + | \ */ + + c=*(cp-*p++);x+=c;y+=c;w+=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p);x+=c;y+=c;w-=c; + p+=x_size-2; + + c=*(cp-*p);x+=c; + p+=2; + c=*(cp-*p);x+=c; + p+=x_size-2; + + c=*(cp-*p++);x+=c;y+=c;w-=c; + c=*(cp-*p++);y+=c; + c=*(cp-*p);x+=c;y+=c;w+=c; + + if (y==0) + z = 1000000.0; + else + z = ((float)x) / ((float)y); + if (z < 0.5) { /* vertical */ a=0; b=1; } + else { if (z > 2.0) { /* horizontal */ a=1; b=0; } + else { /* diagonal */ if (w>0) { a=-1; b=1; } + else { a=1; b=1; } + } + } + if ( (m > r[(i+a)*x_size+j+b]) && (m >= r[(i-a)*x_size+j-b]) ) { + mid[i*x_size+j] = 2; + } + } + } + } + } +} + + +void susan_corner_draw( uchar *in, CORNER_LIST corner_list, + int x_size, int drawing_mode) +{ + uchar *p; + int n=0; + + _Pragma( "loopbound min 0 max 0" ) + while(corner_list[n].info != 7) { + if (drawing_mode==0) { + p = in + (corner_list[n].y-1)*x_size + corner_list[n].x - 1; + *p++=255; *p++=255; *p=255; p+=x_size-2; + *p++=255; *p++=0; *p=255; p+=x_size-2; + *p++=255; *p++=255; *p=255; + n++; + } else { + p = in + corner_list[n].y*x_size + corner_list[n].x; + *p=0; + n++; + } + } +} + + +void susan_corners( uchar *in, char *r, uchar *bp, + int max_no, CORNER_LIST corner_list, int x_size, int y_size) +{ + int n,x,y,sq,xx,yy, + i,j; + float divide; + uchar c,*p,*cp; + char *cgx,*cgy; + + susan_wccmemset(r,0,x_size * y_size); + + cgx=(char *)susan_wccmalloc(x_size*y_size); + cgy=(char *)susan_wccmalloc(x_size*y_size); + + _Pragma( "loopbound min 85 max 85" ) + for (i=5;i ((n*n)/2) ) { + if(yy290){ + r[i*x_size+j] = max_no-n; + cgx[i*x_size+j] = (51*x)/n; + cgy[i*x_size+j] = (51*y)/n; + } + } + } + }}}}}}}}}}}}}}}}}} + } + } + + /* to locate the local maxima */ + n=0; + _Pragma( "loopbound min 85 max 85" ) + for (i=5;i0) { + /* 5x5 mask */ + #ifdef FIVE_SUPP + if ((x>r[(i-1)*x_size+j+2]) && + (x>r[(i )*x_size+j+1]) && + (x>r[(i )*x_size+j+2]) && + (x>r[(i+1)*x_size+j-1]) && + (x>r[(i+1)*x_size+j ]) && + (x>r[(i+1)*x_size+j+1]) && + (x>r[(i+1)*x_size+j+2]) && + (x>r[(i+2)*x_size+j-2]) && + (x>r[(i+2)*x_size+j-1]) && + (x>r[(i+2)*x_size+j ]) && + (x>r[(i+2)*x_size+j+1]) && + (x>r[(i+2)*x_size+j+2]) && + (x>=r[(i-2)*x_size+j-2]) && + (x>=r[(i-2)*x_size+j-1]) && + (x>=r[(i-2)*x_size+j ]) && + (x>=r[(i-2)*x_size+j+1]) && + (x>=r[(i-2)*x_size+j+2]) && + (x>=r[(i-1)*x_size+j-2]) && + (x>=r[(i-1)*x_size+j-1]) && + (x>=r[(i-1)*x_size+j ]) && + (x>=r[(i-1)*x_size+j+1]) && + (x>=r[(i )*x_size+j-2]) && + (x>=r[(i )*x_size+j-1]) && + (x>=r[(i+1)*x_size+j-2]) ) + #endif + #ifdef SEVEN_SUPP + if ((x>r[(i-3)*x_size+j-3]) && + (x>r[(i-3)*x_size+j-2]) && + (x>r[(i-3)*x_size+j-1]) && + (x>r[(i-3)*x_size+j ]) && + (x>r[(i-3)*x_size+j+1]) && + (x>r[(i-3)*x_size+j+2]) && + (x>r[(i-3)*x_size+j+3]) && + + (x>r[(i-2)*x_size+j-3]) && + (x>r[(i-2)*x_size+j-2]) && + (x>r[(i-2)*x_size+j-1]) && + (x>r[(i-2)*x_size+j ]) && + (x>r[(i-2)*x_size+j+1]) && + (x>r[(i-2)*x_size+j+2]) && + (x>r[(i-2)*x_size+j+3]) && + + (x>r[(i-1)*x_size+j-3]) && + (x>r[(i-1)*x_size+j-2]) && + (x>r[(i-1)*x_size+j-1]) && + (x>r[(i-1)*x_size+j ]) && + (x>r[(i-1)*x_size+j+1]) && + (x>r[(i-1)*x_size+j+2]) && + (x>r[(i-1)*x_size+j+3]) && + + (x>r[(i)*x_size+j-3]) && + (x>r[(i)*x_size+j-2]) && + (x>r[(i)*x_size+j-1]) && + (x>=r[(i)*x_size+j+1]) && + (x>=r[(i)*x_size+j+2]) && + (x>=r[(i)*x_size+j+3]) && + + (x>=r[(i+1)*x_size+j-3]) && + (x>=r[(i+1)*x_size+j-2]) && + (x>=r[(i+1)*x_size+j-1]) && + (x>=r[(i+1)*x_size+j ]) && + (x>=r[(i+1)*x_size+j+1]) && + (x>=r[(i+1)*x_size+j+2]) && + (x>=r[(i+1)*x_size+j+3]) && + + (x>=r[(i+2)*x_size+j-3]) && + (x>=r[(i+2)*x_size+j-2]) && + (x>=r[(i+2)*x_size+j-1]) && + (x>=r[(i+2)*x_size+j ]) && + (x>=r[(i+2)*x_size+j+1]) && + (x>=r[(i+2)*x_size+j+2]) && + (x>=r[(i+2)*x_size+j+3]) && + + (x>=r[(i+3)*x_size+j-3]) && + (x>=r[(i+3)*x_size+j-2]) && + (x>=r[(i+3)*x_size+j-1]) && + (x>=r[(i+3)*x_size+j ]) && + (x>=r[(i+3)*x_size+j+1]) && + (x>=r[(i+3)*x_size+j+2]) && + (x>=r[(i+3)*x_size+j+3]) ) + #endif + { + corner_list[n].info=0; + corner_list[n].x=j; + corner_list[n].y=i; + corner_list[n].dx=cgx[i*x_size+j]; + corner_list[n].dy=cgy[i*x_size+j]; + corner_list[n].I=in[i*x_size+j]; + n++; + if(n==MAX_CORNERS){ + /* "Too many corners." */ + } + } + } + } + } + corner_list[n].info=7; +} + + +void susan_corners_quick( uchar *in, char *r, uchar *bp, + int max_no, CORNER_LIST corner_list, int x_size, int y_size ) +{ + int n,x,y,i,j; + uchar *p,*cp; + + susan_wccmemset(r,0,x_size * y_size); + + _Pragma( "loopbound min 0 max 0" ) + for (i=7;i0) { + /* 5x5 mask */ + #ifdef FIVE_SUPP + if ((x>r[(i-1)*x_size+j+2]) && + (x>r[(i )*x_size+j+1]) && + (x>r[(i )*x_size+j+2]) && + (x>r[(i+1)*x_size+j-1]) && + (x>r[(i+1)*x_size+j ]) && + (x>r[(i+1)*x_size+j+1]) && + (x>r[(i+1)*x_size+j+2]) && + (x>r[(i+2)*x_size+j-2]) && + (x>r[(i+2)*x_size+j-1]) && + (x>r[(i+2)*x_size+j ]) && + (x>r[(i+2)*x_size+j+1]) && + (x>r[(i+2)*x_size+j+2]) && + (x>=r[(i-2)*x_size+j-2]) && + (x>=r[(i-2)*x_size+j-1]) && + (x>=r[(i-2)*x_size+j ]) && + (x>=r[(i-2)*x_size+j+1]) && + (x>=r[(i-2)*x_size+j+2]) && + (x>=r[(i-1)*x_size+j-2]) && + (x>=r[(i-1)*x_size+j-1]) && + (x>=r[(i-1)*x_size+j ]) && + (x>=r[(i-1)*x_size+j+1]) && + (x>=r[(i )*x_size+j-2]) && + (x>=r[(i )*x_size+j-1]) && + (x>=r[(i+1)*x_size+j-2]) ) + #endif + #ifdef SEVEN_SUPP + if ((x>r[(i-3)*x_size+j-3]) && + (x>r[(i-3)*x_size+j-2]) && + (x>r[(i-3)*x_size+j-1]) && + (x>r[(i-3)*x_size+j ]) && + (x>r[(i-3)*x_size+j+1]) && + (x>r[(i-3)*x_size+j+2]) && + (x>r[(i-3)*x_size+j+3]) && + + (x>r[(i-2)*x_size+j-3]) && + (x>r[(i-2)*x_size+j-2]) && + (x>r[(i-2)*x_size+j-1]) && + (x>r[(i-2)*x_size+j ]) && + (x>r[(i-2)*x_size+j+1]) && + (x>r[(i-2)*x_size+j+2]) && + (x>r[(i-2)*x_size+j+3]) && + + (x>r[(i-1)*x_size+j-3]) && + (x>r[(i-1)*x_size+j-2]) && + (x>r[(i-1)*x_size+j-1]) && + (x>r[(i-1)*x_size+j ]) && + (x>r[(i-1)*x_size+j+1]) && + (x>r[(i-1)*x_size+j+2]) && + (x>r[(i-1)*x_size+j+3]) && + + (x>r[(i)*x_size+j-3]) && + (x>r[(i)*x_size+j-2]) && + (x>r[(i)*x_size+j-1]) && + (x>=r[(i)*x_size+j+1]) && + (x>=r[(i)*x_size+j+2]) && + (x>=r[(i)*x_size+j+3]) && + + (x>=r[(i+1)*x_size+j-3]) && + (x>=r[(i+1)*x_size+j-2]) && + (x>=r[(i+1)*x_size+j-1]) && + (x>=r[(i+1)*x_size+j ]) && + (x>=r[(i+1)*x_size+j+1]) && + (x>=r[(i+1)*x_size+j+2]) && + (x>=r[(i+1)*x_size+j+3]) && + + (x>=r[(i+2)*x_size+j-3]) && + (x>=r[(i+2)*x_size+j-2]) && + (x>=r[(i+2)*x_size+j-1]) && + (x>=r[(i+2)*x_size+j ]) && + (x>=r[(i+2)*x_size+j+1]) && + (x>=r[(i+2)*x_size+j+2]) && + (x>=r[(i+2)*x_size+j+3]) && + + (x>=r[(i+3)*x_size+j-3]) && + (x>=r[(i+3)*x_size+j-2]) && + (x>=r[(i+3)*x_size+j-1]) && + (x>=r[(i+3)*x_size+j ]) && + (x>=r[(i+3)*x_size+j+1]) && + (x>=r[(i+3)*x_size+j+2]) && + (x>=r[(i+3)*x_size+j+3]) ) + #endif + { + corner_list[n].info=0; + corner_list[n].x=j; + corner_list[n].y=i; + x = in[(i-2)*x_size+j-2] + in[(i-2)*x_size+j-1] + in[(i-2)*x_size+j] + in[(i-2)*x_size+j+1] + in[(i-2)*x_size+j+2] + + in[(i-1)*x_size+j-2] + in[(i-1)*x_size+j-1] + in[(i-1)*x_size+j] + in[(i-1)*x_size+j+1] + in[(i-1)*x_size+j+2] + + in[(i )*x_size+j-2] + in[(i )*x_size+j-1] + in[(i )*x_size+j] + in[(i )*x_size+j+1] + in[(i )*x_size+j+2] + + in[(i+1)*x_size+j-2] + in[(i+1)*x_size+j-1] + in[(i+1)*x_size+j] + in[(i+1)*x_size+j+1] + in[(i+1)*x_size+j+2] + + in[(i+2)*x_size+j-2] + in[(i+2)*x_size+j-1] + in[(i+2)*x_size+j] + in[(i+2)*x_size+j+1] + in[(i+2)*x_size+j+2]; + + corner_list[n].I=x/25; + /*corner_list[n].I=in[i*x_size+j];*/ + x = in[(i-2)*x_size+j+2] + in[(i-1)*x_size+j+2] + in[(i)*x_size+j+2] + in[(i+1)*x_size+j+2] + in[(i+2)*x_size+j+2] - + (in[(i-2)*x_size+j-2] + in[(i-1)*x_size+j-2] + in[(i)*x_size+j-2] + in[(i+1)*x_size+j-2] + in[(i+2)*x_size+j-2]); + x += x + in[(i-2)*x_size+j+1] + in[(i-1)*x_size+j+1] + in[(i)*x_size+j+1] + in[(i+1)*x_size+j+1] + in[(i+2)*x_size+j+1] - + (in[(i-2)*x_size+j-1] + in[(i-1)*x_size+j-1] + in[(i)*x_size+j-1] + in[(i+1)*x_size+j-1] + in[(i+2)*x_size+j-1]); + + y = in[(i+2)*x_size+j-2] + in[(i+2)*x_size+j-1] + in[(i+2)*x_size+j] + in[(i+2)*x_size+j+1] + in[(i+2)*x_size+j+2] - + (in[(i-2)*x_size+j-2] + in[(i-2)*x_size+j-1] + in[(i-2)*x_size+j] + in[(i-2)*x_size+j+1] + in[(i-2)*x_size+j+2]); + y += y + in[(i+1)*x_size+j-2] + in[(i+1)*x_size+j-1] + in[(i+1)*x_size+j] + in[(i+1)*x_size+j+1] + in[(i+1)*x_size+j+2] - + (in[(i-1)*x_size+j-2] + in[(i-1)*x_size+j-1] + in[(i-1)*x_size+j] + in[(i-1)*x_size+j+1] + in[(i-1)*x_size+j+2]); + corner_list[n].dx=x/15; + corner_list[n].dy=y/15; + n++; + if(n==MAX_CORNERS){ + /* "Too many corners." */ + } + } + } + } + } + corner_list[n].info=7; +} + + +void susan_call_susan( struct wccFILE *inputFile, int mode ) +{ + uchar *in, *bp, *mid; + int x_size, y_size; + char *r; + CORNER_LIST corner_list; + + susan_get_image( inputFile, &in, &x_size, &y_size ); + + if (susan_dt<0) susan_three_by_three=1; + if ( (susan_principle_conf==1) && (mode==0) ) + mode=1; + + switch (mode) { + case 0: + /* {{{ smoothing */ + + susan_setup_brightness_lut(&bp,susan_bt,2); + susan_smoothing(susan_three_by_three,in,susan_dt,x_size,y_size,bp); + + break; + case 1: + /* {{{ edges */ + + r = (char *) susan_wccmalloc(x_size * y_size); + susan_setup_brightness_lut(&bp,susan_bt,6); + + if (susan_principle_conf) { + if (susan_three_by_three) + susan_principle_small(in,r,bp,susan_max_no_edges,x_size,y_size); + else + susan_principle(in,r,bp,susan_max_no_edges,x_size,y_size); + susan_int_to_uchar(r,in,x_size*y_size); + } else { + mid = (uchar *)susan_wccmalloc(x_size*y_size); + susan_wccmemset(mid,100,x_size * y_size); /* note not set to zero */ + + if (susan_three_by_three) + susan_edges_small(in,r,mid,bp,susan_max_no_edges,x_size,y_size); + else + susan_edges(in,r,mid,bp,susan_max_no_edges,x_size,y_size); + if(susan_thin_post_proc) + susan_thin(r,mid,x_size,y_size); + susan_edge_draw(in,mid,x_size,y_size,susan_drawing_mode); + } + + break; + case 2: + /* {{{ corners */ + + r = (char *) susan_wccmalloc(x_size * y_size); + susan_setup_brightness_lut(&bp,susan_bt,6); + + if (susan_principle_conf) { + susan_principle(in,r,bp,susan_max_no_corners,x_size,y_size); + susan_int_to_uchar(r,in,x_size*y_size); + } else { + if(susan_susan_quick) + susan_corners_quick(in,r,bp,susan_max_no_corners,corner_list,x_size,y_size); + else + susan_corners(in,r,bp,susan_max_no_corners,corner_list,x_size,y_size); + susan_corner_draw(in,corner_list,x_size,susan_drawing_mode); + } + + break; + } + + susan_put_image(x_size,y_size); +} + +void susan_init( void ) +{ + volatile int a = 0; + susan_file.data = susan_input; + susan_file.size = 7292; + susan_file.size += a; + susan_file.cur_pos = 0; + susan_file.cur_pos += a; + + susan_dt = 4.0; + susan_dt += a; + susan_bt = 20; + susan_bt += a; + susan_principle_conf = 0; + susan_principle_conf += a; + susan_thin_post_proc = 1; + susan_thin_post_proc += a; + susan_three_by_three = 0; + susan_three_by_three += a; + susan_drawing_mode = 0; + susan_drawing_mode += a; + susan_susan_quick = 0; + susan_susan_quick += a; + susan_max_no_corners = 50; + susan_max_no_corners += a; + susan_max_no_edges = 50; + susan_max_no_edges += a; + + // mode=0; /* Smoothing mode */ + // mode=1; /* Edges mode */ + // mode=2; /* Corners mode */ + + // principle=1; /* Output initial enhancement image only; corners or edges mode (default is edges mode) */ + // thin_post_proc=0; /* No post-processing on the binary edge map (runs much faster); edges mode */ + // drawing_mode=1; /* Mark corners/edges with single black points instead of black with white border; corners or edges mode */ + // three_by_three=1; /* Use flat 3x3 mask, edges or smoothing mode */ + // susan_quick=1; /* Use faster (and usually stabler) corner mode; edge-like corner suppression not carried out; corners mode */ + // dt=10.0; /* Distance threshold, smoothing mode, (default=4) */ + // bt=50; /* Brightness threshold, all modes, (default=20) */ +} + +void susan_main( void ) +{ + susan_call_susan( &susan_file, 0 ); + susan_wccfreeall(); + susan_call_susan( &susan_file, 1 ); + susan_wccfreeall(); + susan_call_susan( &susan_file, 2 ); + susan_wccfreeall(); +} + +int susan_return( void ) +{ + return 0; +} + +int main( int argc, char **argv ) +{ + SET_UP + for (jobsComplete=-1; jobsCompletecur_pos, i2 = 0; + size_x number_of_chars_to_read = + stream->size - stream->cur_pos >= size * count ? + size * count : stream->size - stream->cur_pos; + _Pragma( "loopbound min 7220 max 7220" ) + while (i < stream->cur_pos + number_of_chars_to_read) { + ((unsigned char*)ptr)[i2++] = stream->data[i++]; + } + stream->cur_pos += number_of_chars_to_read; + return number_of_chars_to_read; +} + +int susan_wccfgetc(struct wccFILE *stream) +{ + if ( susan_wccfeof( stream ) ) { + return EOFX; + } else { + return stream->data[stream->cur_pos++]; + } +} + +char *susan_wccfgets(char *str, int num, struct wccFILE *stream ) +{ + if ( !stream || susan_wccfeof( stream ) || !str || num <= 0 ) { + return 0; + } + + int pos = 0; + _Pragma( "loopbound min 58 max 58" ) + while ( pos < num - 1 && !susan_wccfeof( stream ) ) { + str[pos] = stream->data[stream->cur_pos]; + if ( str[pos] == '\n' ) { + break; + } + + stream->cur_pos++; + pos++; + } + str[pos++] = '\0'; + + return str; +} + +int susan_wccfseek(struct wccFILE* stream, long int offset, enum _Origin_ origin) +{ + if (origin == WCCSEEK_SET) { + stream->cur_pos = offset; + return 0; + } else if (origin == WCCSEEK_CUR) { + stream->cur_pos += offset; + return 0; + } else if (origin == WCCSEEK_END) { + stream->cur_pos = stream->size + offset; + return 0; + } + return -1; +} + + +int susan_wccfgetpos(struct wccFILE* stream, unsigned* position) +{ + *position = stream->cur_pos; + return 0; +} + + +int susan_wccfeof(struct wccFILE* stream) +{ + return stream->cur_pos == stream->size ? 1 : 0; +} diff --git a/baseline/source/susan/wccfile.h b/baseline/source/susan/wccfile.h new file mode 100644 index 0000000..9314361 --- /dev/null +++ b/baseline/source/susan/wccfile.h @@ -0,0 +1,24 @@ +#ifndef WCC_FILE_H +#define WCC_FILE_H + +enum _Origin_ { WCCSEEK_SET, WCCSEEK_CUR, WCCSEEK_END }; +typedef enum _Origin_ Origin; +typedef unsigned int size_x; + +#define EOFX -1 + +struct wccFILE { + char* data; + size_x size; + unsigned cur_pos; +}; + +size_x susan_wccfread (void* ptr, size_x size, size_x count, struct wccFILE* stream); +int susan_wccfseek (struct wccFILE* stream, long int offset, Origin origin); +int susan_wccfgetpos (struct wccFILE* stream, unsigned* position); +int susan_wccfeof (struct wccFILE* stream); +int susan_wccfgetc (struct wccFILE *stream); +char *susan_wccfgets (char *str, int num, struct wccFILE *stream ); + +#endif + diff --git a/baseline/source/susan/wcclibm.c b/baseline/source/susan/wcclibm.c new file mode 100644 index 0000000..bca8907 --- /dev/null +++ b/baseline/source/susan/wcclibm.c @@ -0,0 +1,444 @@ +#include "math_private.h" +#include "wcclibm.h" + + + +/* e_rem_pio2f.c -- float version of e_rem_pio2.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_rem_pio2f.c,v 1.5 1995/05/10 20:46:03 jtc Exp $"; +#endif + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2f() + */ + +/* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ +static const int32_t susan_npio2_hw[] = { +0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, +0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, +0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, +0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, +0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, +0x4242c700, 0x42490f00 +}; + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +static const float +/* zero = 0.0000000000e+00f, /\* 0x00000000 *\/ */ +/* half = 5.0000000000e-01f, /\* 0x3f000000 *\/ */ +/* two8 = 2.5600000000e+02f, /\* 0x43800000 *\/ */ +susan_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ +susan_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ +susan_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ +susan_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ +susan_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ +susan_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ +susan_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + +int32_t susan___ieee754_rem_pio2f(float x, float *y) +{ + float z,w,t,r,fn; + int32_t i,j,n,ix,hx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - susan_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - susan_pio2_1t; + y[1] = (z-y[0])-susan_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= susan_pio2_2; + y[0] = z - susan_pio2_2t; + y[1] = (z-y[0])-susan_pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + susan_pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + susan_pio2_1t; + y[1] = (z-y[0])+susan_pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += susan_pio2_2; + y[0] = z + susan_pio2_2t; + y[1] = (z-y[0])+susan_pio2_2t; + } + return -1; + } + } + if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (int32_t) (t*susan_invpio2+susan_half); + fn = (float)n; + r = t-fn*susan_pio2_1; + w = fn*susan_pio2_1t; /* 1st round good to 40 bit */ + if(n<32&&(int32_t)(ix&0xffffff00)!=susan_npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix>>23; + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*susan_pio2_2; + r = t-w; + w = fn*susan_pio2_2t-((t-r)-w); + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*susan_pio2_3; + r = t-w; + w = fn*susan_pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7f800000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + + y[0]=y[1]=x-x; return 0; /* dummy initialisation */ + return 0; /* doesn't happen for our input */ +} + +/* k_cosf.c -- float version of k_cos.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_cosf.c,v 1.4 1995/05/10 20:46:23 jtc Exp $"; +#endif + + +static const float +/* one = 1.0000000000e+00, /\* 0x3f800000 *\/ */ +susan_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ +susan_C2 = -1.3888889225e-03f, /* 0xbab60b61 */ +susan_C3 = 2.4801587642e-05f, /* 0x37d00d01 */ +susan_C4 = -2.7557314297e-07f, /* 0xb493f27c */ +susan_C5 = 2.0875723372e-09f, /* 0x310f74f6 */ +susan_C6 = -1.1359647598e-11f; /* 0xad47d74e */ + +float susan___kernel_cosf(float x, float y) +{ + float a,hz,z,r,qx; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x32000000) { /* if x < 2**27 */ + if(((int)x)==0) return susan_one; /* generate inexact */ + } + z = x*x; + r = z*(susan_C1+z*(susan_C2+z*(susan_C3+z*(susan_C4+z*(susan_C5+z*susan_C6))))); + if(ix < 0x3e99999a) /* if |x| < 0.3 */ + return susan_one - ((float)0.5f*z - (z*r - x*y)); + else { + if(ix > 0x3f480000) { /* x > 0.78125 */ + qx = (float)0.28125f; + } else { + SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ + } + hz = (float)0.5f*z-qx; + a = susan_one-qx; + return a - (hz - (z*r-x*y)); + } +} + +/* k_sinf.c -- float version of k_sin.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4 1995/05/10 20:46:33 jtc Exp $"; +#endif + + +static const float +/* half = 5.0000000000e-01f,/\* 0x3f000000 *\/ */ +susan_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ +susan_S2 = 8.3333337680e-03f, /* 0x3c088889 */ +susan_S3 = -1.9841270114e-04f, /* 0xb9500d01 */ +susan_S4 = 2.7557314297e-06f, /* 0x3638ef1b */ +susan_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ +susan_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ + +float susan___kernel_sinf(float x, float y, int iy) +{ + float z,r,v; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x32000000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = susan_S2+z*(susan_S3+z*(susan_S4+z*(susan_S5+z*susan_S6))); + if(iy==0) return x+v*(susan_S1+z*r); + else return x-((z*(susan_half*y-v*r)-y)-v*susan_S1); +} +/* s_atanf.c -- float version of s_atan.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_atanf.c,v 1.4 1995/05/10 20:46:47 jtc Exp $"; +#endif + + +static const float susan_atanhi[] = { + 4.6364760399e-01f, /* atan(0.5)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ +}; + +static const float susan_atanlo[] = { + 5.0121582440e-09f, /* atan(0.5)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ +}; + +static const float susan_aT[] = { + 3.3333334327e-01f, /* 0x3eaaaaaa */ + -2.0000000298e-01f, /* 0xbe4ccccd */ + 1.4285714924e-01f, /* 0x3e124925 */ + -1.1111110449e-01f, /* 0xbde38e38 */ + 9.0908870101e-02f, /* 0x3dba2e6e */ + -7.6918758452e-02f, /* 0xbd9d8795 */ + 6.6610731184e-02f, /* 0x3d886b35 */ + -5.8335702866e-02f, /* 0xbd6ef16b */ + 4.9768779427e-02f, /* 0x3d4bda59 */ + -3.6531571299e-02f, /* 0xbd15a221 */ + 1.6285819933e-02f, /* 0x3c8569d7 */ +}; + +float susan___atanf(float x) +{ + float w,s1,s2,z; + int32_t ix,hx,id; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x50800000) { /* if |x| >= 2^34 */ + if(ix>0x7f800000) + return x+x; /* NaN */ + if(hx>0) return susan_atanhi[3]+susan_atanlo[3]; + else return -susan_atanhi[3]-susan_atanlo[3]; + } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ + if (ix < 0x31000000) { /* |x| < 2^-29 */ + if(susan_huge+x>susan_one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsf(x); + if (ix < 0x3f980000) { /* |x| < 1.1875 */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = ((float)2.0f*x-susan_one)/((float)2.0f+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-susan_one)/(x+susan_one); + } + } else { + if (ix < 0x401c0000) { /* |x| < 2.4375 */ + id = 2; x = (x-(float)1.5f)/(susan_one+(float)1.5f*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -(float)1.0f/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(susan_aT[0]+w*(susan_aT[2]+w*(susan_aT[4]+w*(susan_aT[6]+w*(susan_aT[8]+w*susan_aT[10]))))); + s2 = w*(susan_aT[1]+w*(susan_aT[3]+w*(susan_aT[5]+w*(susan_aT[7]+w*susan_aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = susan_atanhi[id] - ((x*(s1+s2) - susan_atanlo[id]) - x); + return (hx<0)? -z:z; + } +} + +/* s_cosf.c -- float version of s_cos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +float susan___cosf(float x) +{ + float y[2],z=0.0f; + int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return susan___kernel_cosf(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = susan___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return susan___kernel_cosf(y[0],y[1]); + case 1: return -susan___kernel_sinf(y[0],y[1],1); + case 2: return -susan___kernel_cosf(y[0],y[1]); + default: + return susan___kernel_sinf(y[0],y[1],1); + } + } +} + +/* s_sinf.c -- float version of s_sin.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +float susan___sinf(float x) +{ + float y[2],z=0.0; + int32_t n, ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return susan___kernel_sinf(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = susan___ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return susan___kernel_sinf(y[0],y[1],1); + case 1: return susan___kernel_cosf(y[0],y[1]); + case 2: return -susan___kernel_sinf(y[0],y[1],1); + default: + return -susan___kernel_cosf(y[0],y[1]); + } + } +} + +/* s_fabsf.c -- float version of s_fabs.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabsf(x) returns the absolute value of x. + */ + + +float susan___fabsf(float x) +{ + u_int32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} diff --git a/baseline/source/susan/wcclibm.h b/baseline/source/susan/wcclibm.h new file mode 100644 index 0000000..bcf4c65 --- /dev/null +++ b/baseline/source/susan/wcclibm.h @@ -0,0 +1,53 @@ +#ifndef _WCCLIBM +#define _WCCLIBM + +#define int32_t int +#define uint32_t unsigned int +#define u_int16_t unsigned short +#define u_int32_t unsigned int + +// Often used variables/consts +#ifdef __STDC__ +static const float +#else +static float +#endif +susan_one = 1.0f, +susan_half = 5.0000000000e-01f, /* 0x3f000000 */ +susan_zero = 0.0f, +susan_huge = 1.0e30, +susan_two8 = 2.5600000000e+02f, /* 0x43800000 */ +susan_twon8 = 3.9062500000e-03f; /* 0x3b800000 */ + +// The following defines map the math functions to specialized calls +#define acos susan___ieee754_acosf +#define atan susan___atanf +#define cos susan___cosf +#define fabs susan___fabsf +#define fabsf susan___fabsf +#define isinf susan___isinff +#define pow susan___ieee754_powf +#define sqrt susan___ieee754_sqrtf +#define log10 susan___ieee754_log10f +#define log susan___ieee754_logf +#define sin susan___sinf + +float susan___atanf(float x); +float susan___copysignf(float x, float y); +float susan___cosf(float x); +float susan___fabsf(float x); +float susan___floorf(float x); +float susan___ieee754_acosf(float x); +float susan___ieee754_powf(float x, float y); +int32_t susan___ieee754_rem_pio2f(float x, float *y); +float susan___ieee754_sqrtf(float x); +int susan___isinff (float x); +float susan___kernel_cosf(float x, float y); +float susan___kernel_sinf(float x, float y, int iy); +int susan___kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2); +float susan___scalbnf (float x, int n); +float susan___ieee754_logf(float x); +float susan___ieee754_log10f(float x); +float susan___sinf(float x); + +#endif // _WCCLIBM diff --git a/baseline/source/susan/wccmalloc.c b/baseline/source/susan/wccmalloc.c new file mode 100644 index 0000000..edf01cc --- /dev/null +++ b/baseline/source/susan/wccmalloc.c @@ -0,0 +1,51 @@ +#include "wccmalloc.h" + +// This must be redefined for each new benchmark +#define HEAP_SIZE 30000 + +char susan_simulated_heap[HEAP_SIZE]; +unsigned int susan_freeHeapPos; + +void* susan_wccmalloc( unsigned int numberOfBytes ) +{ + // Get a 4-byte adress for alignment purposes + unsigned int offset = ( (unsigned long)susan_simulated_heap + susan_freeHeapPos ) % 4; + if ( offset ) { + susan_freeHeapPos += 4 - offset; + } + void* currentPos = (void*)&susan_simulated_heap[susan_freeHeapPos]; + susan_freeHeapPos += numberOfBytes; + return currentPos; +} +void susan_wccfreeall( void ) +{ + susan_freeHeapPos = 0; +} + +void* susan_wccmemcpy(void* dstpp, const void* srcpp, unsigned int len) +{ + unsigned long int dstp = (long int) dstpp; + unsigned long int srcp = (long int) srcpp; + + _Pragma("loopbound min 76 max 76") + while (len > 0) { + char __x = ((char *) srcp)[0]; + srcp += 1; + len -= 1; + ((char *) dstp)[0] = __x; + dstp += 1; + } + + return dstpp; +} + +void susan_wccmemset( void *p, int value, unsigned int num ) +{ + unsigned long i; + char *char_ptr = (char*)p; + + _Pragma( "loopbound min 7220 max 28880" ) + for ( i = 0; i < num; ++i ) { + *char_ptr++ = (unsigned char)value; + } +} diff --git a/baseline/source/susan/wccmalloc.h b/baseline/source/susan/wccmalloc.h new file mode 100644 index 0000000..dbb2ada --- /dev/null +++ b/baseline/source/susan/wccmalloc.h @@ -0,0 +1,10 @@ +#ifndef _WCCMALLOC_H +#define _WCCMALLOC_H + +void* susan_wccmalloc( unsigned int numberOfBytes ); +//! Frees ALL allocated memory space +void susan_wccfreeall( void ); +void *susan_wccmemcpy( void* dstpp, const void* srcpp, unsigned int len ); +void susan_wccmemset( void *p, int value, unsigned int num ); + +#endif diff --git a/baseline/tacleNames.txt b/baseline/tacleNames.txt new file mode 100644 index 0000000..8f4845a --- /dev/null +++ b/baseline/tacleNames.txt @@ -0,0 +1,19 @@ +petrinet +ndes +statemate +adpcm_dec +cjpeg_wrbmp +adpcm_enc +cjpeg_transupp +dijkstra +epic +fmref +gsm_dec +h264_dec +huff_enc +rijndael_enc +rijndael_dec +gsm_enc +susan +ammunition +mpeg2 diff --git a/rtss19/extra.h b/rtss19/extra.h deleted file mode 100644 index b96671c..0000000 --- a/rtss19/extra.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Copyright 2019 Sims Hill Osborne and Joshua Bakita - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - **/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Benchmarks use SET_UP, START_LOOP, STOP_LOOP, and WRITE_TO_FILE -// These are macros so that we can declare and maintain additional state inside -// the benchmark. -#define SET_UP if (argc < 8) {\ - printf("Usage: %s ", argv[0]);\ - exit(1);\ - }\ - char * thisProgram = argv[1];\ - unsigned int maxJobs = atoi(argv[2]);\ - char * thisCore = argv[3];\ - char * otherCore = argv[4];\ - char * otherProgram = argv[5];\ - char * runID = argv[6];\ - int lockID = atoi(argv[7]);\ - struct timespec start, end;\ - unsigned int jobsComplete = 0;\ - long * startS = malloc(sizeof(long) *maxJobs);\ - long * startN = malloc(sizeof(long) *maxJobs);\ - long * endS = malloc(sizeof(long) *maxJobs);\ - long * endN = malloc(sizeof(long) *maxJobs);\ - char * bigArray;\ - char fileName[strlen(runID) + 5];\ - strcpy(fileName, runID);\ - strcat(fileName, ".txt");\ - mlockall(MCL_CURRENT || MCL_FUTURE);\ - sem_t *firstSem=sem_open("/firstTacleSem", O_CREAT, 644, 0);\ - if (firstSem == SEM_FAILED) {\ - perror("Error opening/creating first semaphore");\ - exit(1);\ - }\ - sem_t *secondSem=sem_open("/secondTacleSem", O_CREAT, 644, 0);\ - if (secondSem == SEM_FAILED) {\ - perror("Error opening/creating second semaphore");\ - exit(1);\ - }\ - int barrier_file = shm_open("/TacleBarrier", O_CREAT | O_RDWR, 644);\ - if (barrier_file == -1) {\ - perror("Error creating shared memory");\ - exit(1);\ - }\ - /* This sets our shared file to be one byte of '\0'*/ \ - if (ftruncate(barrier_file, 1) == -1) {\ - perror("Error setting size of shared memory");\ - exit(1);\ - }\ - char * barrier = mmap(NULL, 1, PROT_WRITE, MAP_SHARED, barrier_file, 0);\ - if (barrier == MAP_FAILED) {\ - perror("Error mapping shared memory");\ - exit(1);\ - }\ - int error;\ - int val; - -#define SAVE_RESULTS if (jobsComplete > 0){\ - startS[jobsComplete]=start.tv_sec;\ - startN[jobsComplete]=start.tv_nsec;\ - endS[jobsComplete]=end.tv_sec;\ - endN[jobsComplete]=end.tv_nsec;} - -#define WRITE_TO_FILE {\ - munlockall();\ - FILE *fp = fopen(fileName, "a");\ - if (fp == NULL) {\ - perror("Error opening file. \n");\ - exit(1);\ - }\ - for(jobsComplete=0; jobsComplete " + exit +fi + +date +cd baseline +make all +../interference-benchmark/deactivateCoresSMT.bash +./run_baseline.sh 15 $maxJobs $runID +date +cd ../all_pairs +../../interference-benchmark/activateCores.bash +make all +./run_all_pairs.sh 15 31 $maxJobs $runID +date -- cgit v1.2.2