From 694817511391747054f7e06ae767c1c8ffc71990 Mon Sep 17 00:00:00 2001 From: cnlohr Date: Sun, 24 Mar 2024 17:33:38 -0700 Subject: [PATCH] Initial Commit --- .gitattributes | 2 + .gitmodules | 6 + LICENSE | 108 + README.md | 260 + ch32v/ch32v003/Makefile | 23 + ch32v/ch32v003/README.md | 7 + ch32v/ch32v003/funconfig.h | 9 + ch32v/ch32v003/loratest.c | 440 + ch32v/ch32v003/rf_data_gen.c | 58 + ch32v/ch32v003fun | 1 + ch32v/ch32v203/Makefile | 23 + ch32v/ch32v203/README.md | 5 + ch32v/ch32v203/funconfig.h | 9 + ch32v/ch32v203/loratest.c | 441 + ch32v/ch32v203/rf_data_gen.c | 91 + esp32s2/loratest/.gitignore | 2 + esp32s2/loratest/CMakeLists.txt | 23 + esp32s2/loratest/main/CMakeLists.txt | 4 + esp32s2/loratest/main/app.c | 454 + esp32s2/loratest/main/main.c | 94 + esp32s2/loratest/main/siggen.h | 287 + esp32s2/loratest/partitions.csv | 7 + esp32s2/loratest/sdkconfig | 1810 ++++ esp32s2/videoending/.gitignore | 2 + esp32s2/videoending/CMakeLists.txt | 23 + esp32s2/videoending/main/CMakeLists.txt | 4 + esp32s2/videoending/main/app.c | 357 + esp32s2/videoending/main/image.h | 421 + esp32s2/videoending/main/main.c | 94 + esp32s2/videoending/main/siggen.h | 1 + esp32s2/videoending/makeending/Makefile | 12 + esp32s2/videoending/makeending/README.txt | 4 + esp32s2/videoending/makeending/imagegen.c | 81 + esp32s2/videoending/makeending/stb_image.h | 7986 +++++++++++++++++ esp32s2/videoending/partitions.csv | 7 + esp32s2/videoending/sdkconfig | 1810 ++++ esp8266/esp8266_i2s_setup.h | 134 + esp8266/example_125k_raw/Makefile | 31 + esp8266/example_125k_raw/README.md | 6 + esp8266/example_125k_raw/compilecount.txt | 1 + esp8266/example_125k_raw/main.c | 378 + esp8266/example_125k_raw/rf_data_gen.c | 65 + esp8266/example_500k_raw/Makefile | 31 + esp8266/example_500k_raw/README.md | 5 + esp8266/example_500k_raw/compilecount.txt | 1 + esp8266/example_500k_raw/main.c | 294 + esp8266/example_500k_raw/rf_data_gen.c | 65 + esp8266/lorawan_example/Makefile | 31 + esp8266/lorawan_example/README.md | 27 + esp8266/lorawan_example/compilecount.txt | 1 + esp8266/lorawan_example/main.c | 333 + esp8266/lorawan_example/reference.txt | 189 + esp8266/lorawan_example/rf_data_gen.c | 65 + esp8266/non_lora_310_transmit/Makefile | 25 + esp8266/non_lora_310_transmit/README.md | 11 + .../non_lora_310_transmit/compilecount.txt | 1 + esp8266/non_lora_310_transmit/main.c | 294 + esp8266/non_lora_310_transmit/rf_data_gen.c | 153 + esp8266/nosdk8266 | 1 + lib/LoRa-SDR-Code.h | 626 ++ lib/aes-cbc-cmac.h | 193 + lib/lorawan_simple.h | 160 + lib/rf_data_gen.h | 344 + lib/tiny-AES-c.h | 704 ++ resources/36mhz-up-the-spectrum.png | Bin 0 -> 65490 bytes resources/CrystalOut.png | Bin 0 -> 101584 bytes resources/RCOut.png | Bin 0 -> 67250 bytes resources/Rangetest.png | Bin 0 -> 108288 bytes resources/SineHarmonics.png | Bin 0 -> 31598 bytes resources/SineTop.png | Bin 0 -> 78877 bytes resources/SquareHarmonics.png | Bin 0 -> 49759 bytes resources/SquareTop.png | Bin 0 -> 72073 bytes resources/UpSpectrumImages.png | Bin 0 -> 65490 bytes resources/UpSpectrumSad.png | Bin 0 -> 44196 bytes resources/bitstreamdiagram.png | Bin 0 -> 222164 bytes tools/60-rtlsdr.rules | 2 + tools/Makefile | 17 + tools/README.md | 14 + tools/complex_magsink_to_image.c | 196 + tools/magsink_to_image.c | 82 + tools/stb_image_write.h | 1725 ++++ tools/testloradec.grc | 1230 +++ 82 files changed, 22401 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitmodules create mode 100644 LICENSE create mode 100644 README.md create mode 100644 ch32v/ch32v003/Makefile create mode 100644 ch32v/ch32v003/README.md create mode 100644 ch32v/ch32v003/funconfig.h create mode 100644 ch32v/ch32v003/loratest.c create mode 100644 ch32v/ch32v003/rf_data_gen.c create mode 160000 ch32v/ch32v003fun create mode 100644 ch32v/ch32v203/Makefile create mode 100644 ch32v/ch32v203/README.md create mode 100644 ch32v/ch32v203/funconfig.h create mode 100644 ch32v/ch32v203/loratest.c create mode 100644 ch32v/ch32v203/rf_data_gen.c create mode 100644 esp32s2/loratest/.gitignore create mode 100644 esp32s2/loratest/CMakeLists.txt create mode 100644 esp32s2/loratest/main/CMakeLists.txt create mode 100644 esp32s2/loratest/main/app.c create mode 100644 esp32s2/loratest/main/main.c create mode 100644 esp32s2/loratest/main/siggen.h create mode 100644 esp32s2/loratest/partitions.csv create mode 100644 esp32s2/loratest/sdkconfig create mode 100644 esp32s2/videoending/.gitignore create mode 100644 esp32s2/videoending/CMakeLists.txt create mode 100644 esp32s2/videoending/main/CMakeLists.txt create mode 100644 esp32s2/videoending/main/app.c create mode 100644 esp32s2/videoending/main/image.h create mode 100644 esp32s2/videoending/main/main.c create mode 100644 esp32s2/videoending/main/siggen.h create mode 100644 esp32s2/videoending/makeending/Makefile create mode 100644 esp32s2/videoending/makeending/README.txt create mode 100644 esp32s2/videoending/makeending/imagegen.c create mode 100644 esp32s2/videoending/makeending/stb_image.h create mode 100644 esp32s2/videoending/partitions.csv create mode 100644 esp32s2/videoending/sdkconfig create mode 100644 esp8266/esp8266_i2s_setup.h create mode 100644 esp8266/example_125k_raw/Makefile create mode 100644 esp8266/example_125k_raw/README.md create mode 100644 esp8266/example_125k_raw/compilecount.txt create mode 100644 esp8266/example_125k_raw/main.c create mode 100644 esp8266/example_125k_raw/rf_data_gen.c create mode 100644 esp8266/example_500k_raw/Makefile create mode 100644 esp8266/example_500k_raw/README.md create mode 100644 esp8266/example_500k_raw/compilecount.txt create mode 100644 esp8266/example_500k_raw/main.c create mode 100644 esp8266/example_500k_raw/rf_data_gen.c create mode 100644 esp8266/lorawan_example/Makefile create mode 100644 esp8266/lorawan_example/README.md create mode 100644 esp8266/lorawan_example/compilecount.txt create mode 100644 esp8266/lorawan_example/main.c create mode 100644 esp8266/lorawan_example/reference.txt create mode 100644 esp8266/lorawan_example/rf_data_gen.c create mode 100644 esp8266/non_lora_310_transmit/Makefile create mode 100644 esp8266/non_lora_310_transmit/README.md create mode 100644 esp8266/non_lora_310_transmit/compilecount.txt create mode 100644 esp8266/non_lora_310_transmit/main.c create mode 100644 esp8266/non_lora_310_transmit/rf_data_gen.c create mode 160000 esp8266/nosdk8266 create mode 100644 lib/LoRa-SDR-Code.h create mode 100644 lib/aes-cbc-cmac.h create mode 100644 lib/lorawan_simple.h create mode 100644 lib/rf_data_gen.h create mode 100644 lib/tiny-AES-c.h create mode 100644 resources/36mhz-up-the-spectrum.png create mode 100644 resources/CrystalOut.png create mode 100644 resources/RCOut.png create mode 100644 resources/Rangetest.png create mode 100644 resources/SineHarmonics.png create mode 100644 resources/SineTop.png create mode 100644 resources/SquareHarmonics.png create mode 100644 resources/SquareTop.png create mode 100644 resources/UpSpectrumImages.png create mode 100644 resources/UpSpectrumSad.png create mode 100644 resources/bitstreamdiagram.png create mode 100644 tools/60-rtlsdr.rules create mode 100644 tools/Makefile create mode 100644 tools/README.md create mode 100644 tools/complex_magsink_to_image.c create mode 100644 tools/magsink_to_image.c create mode 100644 tools/stb_image_write.h create mode 100644 tools/testloradec.grc diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..87f9fbc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.h linguist-language=c +CMakeLists.txt linguist-language=idf diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0412a6f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "esp8266/nosdk8266"] + path = esp8266/nosdk8266 + url = https://github.com/cnlohr/nosdk8266 +[submodule "ch32v/ch32v003fun"] + path = ch32v/ch32v003fun + url = https://github.com/cnlohr/ch32v003fun diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1b5d56e --- /dev/null +++ b/LICENSE @@ -0,0 +1,108 @@ +PLEASE NOTE: Files in this project are under multiple licenses. + +Most files are under a regular MIT license, BUT not the RF-related files. + +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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. + + + + + +FOR FILES MARKED WITH A NO-AI-TRAINING TAG, THEY ARE UNDER THIS LICENSE: + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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. + + +FOR THE AES LIBRARY: + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + + +and for portions of LoRa-SDR-Code.h that have not yet been rewritten: + +// Copyright (c) 2016-2016 Lime Microsystems +// Copyright (c) 2016-2016 Arne Hennig +// SPDX-License-Identifier: BSL-1.0 +// from https://github.com/myriadrf/LoRa-SDR/blob/master/LoRaEncoder.cpp + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..470c6b1 --- /dev/null +++ b/README.md @@ -0,0 +1,260 @@ +# LoLRa + +*Transmit 900MHz LoRa frames surprisingly far without a radio* + + * [Introduction](#introduction) + * [Background](#background) + * [LoRaWAN](#lorawan) + * [Limitations](#limitations) + * [Future Work](#future_Work) + * [Resources](#resources) + * [Special Thanks](#special_thanks) + * [Range Tests](#range_tests) + +## Introduction + +Firmware-only LoRa transmission, for a variety of processors. Send LoRa packets, without any radio, chips, external hardware or built-in radios at all on a variety of common, inexpensive processors. While not truly bit banging, this repository shows how using either a shift register (i.e. I2S or SPI port) or an APLL, you can send LoRa packets that can be decoded by commercial off the shelf LoRa gateways and other chips. + +> [!NOTE] +> This repo is designed for use with ITU Region 2 (The Americas) tageting 902-928MHz. Code changes are needed for use in Region 1 (EU, Russia, Afraica) to target 863-870MHz or Region 3 (Australia, China, India) to target 920-923MHz. + +> [!CAUTION] +> Because we rely on harmonics and aliasing, the primary frequency components emitted by your microcontroller are going to be in portions of the RF spectrum where RF transmissions are banned. Please filter your output or perform your tests in an area where you are unlikely to leak significant RF. The overall EIRP output is genreally ≪300uW across the whole spectrum spread out over hundreds of emission frequencies, but there is virtually no way a device deliberately transmitting on these frequencies could ever pass FCC part 15 compliance, even with filtering. + +There are two major modes that this repository works with. + +1. Transmission using a tunable PLL, creating a square wave, then using a harmonic (the 13th harmonic in the case of the ESP32-S2) and then transmitting the signal out a clock out pin. +2. Direct synthesis on a bitstream, a much more versatile method able to work on a myriad of microcontrollers. This creates an image of the intended bitstream up at 900 MHz, even in situations where the bitstream itself can be as low as 7.2 MSPS. But for most platforms, I've targeted between 24 and 173 MSPS. + + +Click Below for the Youtube Video version of this page: + +[![LoRa Without A Radio](https://i3.ytimg.com/vi/eIdHBDSQHyw/maxresdefault.jpg)](https://www.youtube.com/watch?v=eIdHBDSQHyw) + +> [!NOTE] +> Portions of code in this repo are under various licenses and cannot be trivially incorporated into other libraries without a bit of a mess, including a no-ai-training license for any of the RF-specific portions of the project. Be cautious when using code from this repo. See ![LICENSE](LICENSE) for more information. + +## Background + +### Square waves, and images + +Any time a signal changes state from low to high or high to low, a disturbance is created in the electromagnetic fields surrounding that wire. Any time. The difference is, are you, as an engineer, going to fear it, squelching it waddling, being afraid of whatever EMI it might cause, or are you going to grab the bull by its horns and emit some artisanally crafted signals? The major principles you will need to understand are: + + * The actual emission of a wave is made from several frequency components at different frequencies and phases. You can read more about it [in this wolfram article](https://mathworld.wolfram.com/FourierSeriesSquareWave.html) or [This 3Brown1Blue Video](https://www.youtube.com/watch?v=spUNpyF58BY) + +![Square 220 Hz](https://github.com/cnlohr/lolra/blob/master/resources/SquareHarmonics.png?raw=true) + + * A pure sinewave has only its principle output wave in frequency space. + +![Sine 220 Hz](https://github.com/cnlohr/lolra/blob/master/resources/SineHarmonics.png?raw=true) + + * You can create a high frequency tone by generating a low frequency tone (Pictured is a 13th harmonic of at 69.420MHz signal) + +![Single Tone](https://github.com/cnlohr/lolra/blob/master/resources/SineTop.png?raw=true) + + * You can spread a signal over an area of spectrum by scanning it between frequencies. (There are other ways, but that isn't LoRa) + +![Signal Spread](https://github.com/cnlohr/lolra/blob/master/resources/SquareTop.png?raw=true) + + * Square waves are actually several "odd harmonic" frequencies all added together. + +![Signal Going Up Spectrum](https://github.com/cnlohr/lolra/blob/master/resources/36mhz-up-the-spectrum.png?raw=true) + + * It is important to note that many more cheap micros frequencies cut off rather quickly at high frequencies. + +![Up Spectrum Sad](https://github.com/cnlohr/lolra/blob/master/resources/UpSpectrumSad.png?raw=true) + +The second principle is signal mixing. If you create a signal, then "mix" it with a high frequency, you get an "image" wrapped around that high frequency. Mixing can be done with diodes, special RF equipment, or even just sampling, like that done by using a shift register, outputting bits at a steady rate. + +![Signal Mixing](https://github.com/cnlohr/lolra/blob/master/resources/UpSpectrumImages.png?raw=true) + +Now the real magic happens, when you realize these two principles actually work together. You get an image at the base band, a reflected image around the sampling frequency, then around ×3 the sampling frequency, you get another 2 images, the forward and reverse. And ×5, and ×7, etc. + +With this, with a precise enough clock, we can arbitrarily generate any frequency we wish, provided there's enough bandwidth left on the GPIO of our micro to generate it, even if the "actual" signal we're generating is much much lower in frequency. + +#### A side-note: RC/RLC oscillators vs crystal oscillators. + +Internal oscillators in microcontrollers aren't only inaccurate, but they also jitter around in frequency. You might think this a negative, but in fact, using the internal oscillator built into micros can often be a lifesaver, getting you past EMI/EMC. Because the internal oscillators aren't just imprecise but jittery, they prevent harmonics of individual frequencies higher up in the spectrum because the clock rate drifts around so heavily. + +Crystal Output: +![Crystal Output](resources/CrystalOut.png) + +RC Output: +![RC Output](resources/RCOut.png) + +### LoRa signals (40,000' view) + +See the section below for the nitty gritty of how LoRa signals *actually work* or the things that none of the other PhDs on the internet ever were willing to tell you about it. + +LoRa typically operates in the 433MHz or the 900MHz spectrum, usually with 125kHz channels. In principle, LoRa creates chirps, starting at one frequency, 62.5kHz below the channel center, then over a short period of time (1.024uS at SF7) the tone creeps up to 62.5kHz above the channel center. + +While LoRa can be used with many different channel widths, 125kHz and 500kHz are both very well supported, whereas other channel widths are not configurable with routers like the LR9. + +![Bitstream Analysis](resources/bitstreamdiagram.png) + +This diagram shows frequency on the X axis, and time on the Y axis (top to bottom)... You can see: + * **𝔸** our output on a platform like the CH32V203 is not perfect, that's because the SPI bus on the CH32V203 glitches by parts of a bit here and there. This causes other, weaker images in the output. But, largely we can produce totally valid and readable (at a long distance) LoRa packets. + * **𝔹** LoRa consists of several upchirps some in a preamble. + * **ℂ** two more upchirps with a phase offset indicating a sync word if we select 0x43 (or 0x34 depending on endian) for the upchirps here, our packets will be decoded and potentially forwarded by commercial LoRa gateways. + * **𝔻** 2.25 down chrips in. That extra .25 causes some pain 😈 (the minimum logical unit is a quarter chirp, not a whole chirp). + * Then a payload where each upchirp is offset by a phase to convey information in **𝔼**. + +Conveniently the window for a given chirp is stable depending on the spreading factor. For the above packet, with SF7, it works out to 1,024us per symbol, or for SF8, 2,048us per symbol. Each symbol/chirp can represent a number of bits, by a phase offset. + +The raw "phase" of a chirp is grey-coded in order to better spread the bit error between bits to higher layers of the process. For instance, if you are off-by-one with regards to the phase you believe the chirp is at, it could be over a boundary from say 0b1111 and 0b10000 and would cause 5 bit errors. By grey coding it, it minimizes the bit errors created by an off-by-one or even a few of the phase. + +After this raw bitstream is decoded from the individual chirps and de-grey-coded (see `encodeHamming84sx`) in [`LoRa-SDR-Code.h`](https://github.com/cnlohr/lolra/blob/master/lib/LoRa-SDR-Code.h), then we transpose/interleve the bits so any one symbol that could get taken out (see `diagonalInterleaveSx`) to spread any errors out so a single lost symbol can be recovered and whitened (I believe this is actually a worthless step in this protocol, correct me if I'm wrong) see `Sx1272ComputeWhitening`. Above whitening is an error correction layer to help fix any of the bit errors that could happen at a lower layer (see `encodeFec`). + +Overall the messages have a header, and a payload. Note that this can be a little tricky, because the header sometimes uses different encoding settings than the payload. And that's it. + +Once you generate properly formatted packets, you can encode them into chirps and transmit them out the wire. + +A more detailed view of the protocol can be found [here, for a more academic view](https://dl.acm.org/doi/10.1145/3546869) and [here for some better examples](https://chrisye-liu.github.io/files/yang22emu.pdf) (though I have found some issues with the correctness/clarity of both documents). + +### Starting the Project + +I started the project with an ESP32-S2 to see if I could output a signal using the internal built-in APLL, and routing the APLL/2 clock out via the IOMUX, and the answer was I could. Because this generates a simple square wave, and square waves have harmonics at F×3, F×5, F×7, etc... up the spectrum, if I set the APLL to 139.06 MHz, it outputs 69.53MHz. The 13th harmonic is 903.9 MHz, or the first 125kHz LoRa channel. Then by tuning the least significant PLL control bits, we can tune it from 903.9 MHz - 62.5kHz to 903.9 + 62.5kHz, by tuning the APLL to 139.06 MHz - 9.62kHz to 139.06 MHz + 9.62 kHz. This lets us generate the characteristic LoRa chirps and indeed this is receivable! + +The ESP32-S2 also has another trick - the GPIO mux is capable of outputting a signal or the inverse of that signal. That way we can differentially create the 139.06MHz signal, boosting the power output by 3dB! + +There are issues with the ESP32-S2, however. Notably that: +1. The APLL is quite rough since it's fundamentally an analog device and struggles to keep tight control on the output signal. +2. Its output looks very unusual, and is something that limits the performance of the sending of frames. +3. Because it is operating down at the F÷13 node, it has to operate over a very, very small window, ±9.62 kHz, which is quite challenging. + +Additioanlly, very few processors even have an APLL, so in spite of this fast success, I decided to move onto... + +### Direct bitstream synthesis + +Several years ago, I did a number of projects that used direct bitstream synthesis to do a few things, like [Broadcasting RF Color NTSC television on Channel 3 with an ESP8266](https://www.youtube.com/watch?v=bcez5pcp55w) or [Using Ethernet Packets to transmit AM radio](https://www.youtube.com/watch?v=-7jlRfqaYuY). One of the neat tricks is, if you transmit a bitstream out on an SPI or I2S shift register, it causes aliasing at the sample rate, with images at F×3, F×5, F×7, etc. But, the neat part is it preserves the size/shape of the transmitted waveform at images/aliases up the spectrum. For Channel 3, the 65MHz signal was being refelcted around the 40MHz sampling rate. Harry Nyquist can go bite a lemon. + +This technique gives an incredible amount of fidelity even in extremely poor situations, unintuitively so. You can create surprisingly precise signals way outside anywhere you would expect them. + +There are several ways to accomplish this, but typically it's easiest with a shift register. A shift register like that in an I2S or SPI bus. And, if you use DMA, you can easily feed the shift register with more data without waking the CPU up every cycle. There are other ways, though, such as directly toggling an IO, or using a timer to turn an IO on and off at the right time, but it's easiest to write code to generate a bitstream and shift it out. + +For shift registers, a few considerations must be made, such as making sure that the endianness and bit widths and memory arrangements are correct, but, in general, you can keep up, and unless there is lag, like time between each word, they are typically able to faithfully-enough represent a bit pattern on output to be transferred and shifted out of a pin. + +The "lohrcut" described in the video involves writing a function that, given a point in time, determines the amplitude of a signal. This function can be to determine the amplitude of a very high frequency signal, then, the sample rate can be whatever physically realizable sample rate that's avaialble. This will create an image of the high frequency signal at a much lower frequency signal, building it out of power between 0 and Fs/2. + +Another concern is flash, on some systems accesses inconsistently or doesn't work well at certain frequencies. In those cases, like on the ESP8266, the tables must be read into RAM and played from there. + +## LoRaWAN + +LoRa frames are totally encapsulated. If you wanted, we could stop here. You could even use a commercial gateway, but without using LoRaWAN, the frames could not be sent to brokers like The Things Network. For instance, if you ran a raspberry pi gateway, you could just accept whatever old LoRa frames you wanted, but, we took this a step further by helping the packets get forwarded around the world. LoRaWAN is "end to end" encryption, in that none of your neighbors, or gateways can read the messages. Though, it is curious - The Things Network CAN read your messages because they have the encryption keys. + +Conveniently, you can call, `GenerateLoRaWANPacket` in [`lib/lorawan_simple.h`](https://github.com/cnlohr/lolra/blob/master/lib/lorawan_simple.h) handles all of the required encapsulation. Simply use this function to generate your frames, and broadcast them! + +### The LoRa Gateway + +We can transmit these messages. Cool. But now to receive them, we will either need a devices like a [LILYGO® T-Beam Meshtastic](https://www.lilygo.cc/products/t-beam-v1-1-esp32-lora-module) or a gateway like a [MikroTik LR9](https://mikrotik.com/product/wap_lr9_kit). The latter is really interesting here because there are thousands of these set up all over the world, and connected to [The Things Network](https://www.thethingsnetwork.org/). That means if we transmit a properly formatted LoRaWAN packet within earshot of one of those gateways, we can get the frame elsewhere on the planet! + +Setup is pretty starightforward. You need to: +1. Create an account (they are free for personal/academic use) +2. Go to your console. +3. Create a new application. +4. Add a new device. +5. Select "Enter end device specifics manually" +6. Select the appropriate frequency plan. NOTE: This repository is designed around US FSB 2 (used by TTN) +7. Use LoRaWAN 1.0.0 +8. "Show advanced activation, LoRaWAN class and cluster settings" +9. Select "Activation by personalization (ABP)" +10. Generate "Device Address", "AppSKey", and "NwkSKey" +11. Select "Register end device" +12. Place these credentials into the file under the LoRaWAN definition. +13. Unless you can guarantee increasing frame IDs, you will need to go to your device and: +14. Select "General Settings" +15. Select "Network Layer" +16. Select "Advanced MAC settings" +17. Select "Resets frame counters" + +> [!NOTE] +> We only focus on LoRa frames that reset frame counters, however, if you can store the last transmitted packet id to non-volatile flash within your part, you can avoid this step. Without this, your device will be subject to replay attacks. + +> [!NOTE] +> If using the MikroTik LR9, be sure to physically open it and plug in the internal antenna. From the factory, it is shipped connected to the outside port. + +## Limitations + +PR's are open if you can figure any of these out! I just spent all the time I plan to spend on this project before I got here. + + * SF <= 6, SF >= 11 are unavailable. I spent 10+ hours trying to figure them out and gave up. + * There seems to be something not quite perfect for some sizes. As in I was getting CRC errors in some places that my code "should" work but doesn't. + * I never got LDRO to work correctly. I believe it might have to do with the LoRa Code Word (prefixing the 2 downchirps) + * The SPI on the ch32v203 still isn't perfect. I was unable to get the I2S engine working, perhaps it doesn't work on the ch32v203? + * The licenses in this project are a hodgepodge. I encourage people to just use this project as a starting point for other work. + +## Future Work + +For LoRa specifically, waves are very well behaved and should be completely creatable with timer circuitry on the fly and should not need any precomputation, but I haven't gotten around to it yet. This would forego the need to have a large table for the chirps flashed into a device. + +I want to also try performing this project using bespoke bit patterns that are more easily created on-the-fly. Also, depending on the exact codes used (possibly by employing technologies related to gold codes) one could even make reception of many signals with the exact same coding possible concurrently. Doing this would make it quite appropriate to implement "printf" on microcontrollers that can be wirelessly received by a central SDR with very low processor space (and performance) overhead. + +Additionally, it would be fun to add a filter, or maybe try to build a filter into a PCB with no components. + +Additionally, additionally, it would be very cool to try to build a Class C amplifier for the 900MHz signal. This would be very cool because it could be efficient, incredibly cheap and simple and also provide as much as 10-20dB of gain! + +## Range Tests + +Urban testing was performed on 2024-02-23, Suburban on 2022-02-26 and Rural testing was performed on 2022-02-27. + +![Range Test](https://github.com/cnlohr/lolra/blob/master/resources/Rangetest.png?raw=true) + +Ranges are peak ranges. Reliable operation ends much earlier. + +For TTGO Lora32, there was a +3dBi antenna added. For the MikroTik LR9, it used the internal antenna. +| Date | Sender | Receiver | SF/CR | BW | Note | Range | Avg End RSSI/SNR | Basis | +|------------|---------------------|--------------|-----------|-----|----------------------------------------------------|---------------|------------------|--------| +| 2024-02-23 | CH32V203 | MikroTik LR9 | SF8/CR48 | 125 | Downtown Bellevue (Urban) | 435' 132m | -98 / -9 | Ground | +| 2024-02-23 | CH32V203 | MikroTik LR9 | SF10/CR48 | 500 | Downtown Bellevue (Urban) | 435' 132m | -90 / -18 | Ground | +| 2024-02-26 | CH32V203 | TTGO Lora32 | SF8/CR48 | 125 | Miramont Park (Light Suburban + Woods) | >576' >176m | -134 / -12 | Ground | +| 2024-02-26 | CH32V203 | TTGO Lora32 | SF8/CR48 | 125 | Poo Poo Point Trailhead (Rural) | >1117' >340m | -123 / -6 | Ground | +| 2024-02-26 | CH32V203 | TTGO Lora32 | SF8/CR48 | 125 | Issaquah Suburb (+Light Trees) | 2200' 669m | -133 / -10 | Ground | +| 2024-02-27 | CH32V203 | TTGO Lora32 | SF8/CR48 | 125 | Meadowbrook (Rural) Red Longer Antenna | 2220' 677m | -135 / -13 | Drone | +| 2024-02-27 | CH32V203 | TTGO Lora32 | SF10/CR48 | 500 | Meadowbrook (Rural) Red Longer Antenna | 1752' 534m | -132 / -16 | Drone | +| 2024-02-27 | CH32V203 | TTGO Lora32 | SF8/CR48 | 125 | Meadowbrook (Rural) OVERVOLT 5V Red Longer Antenna | 3996' 1218m | -131 / -12 | Drone | +| 2024-02-27 | CH32V203 | TTGO Lora32 | SF8/CR48 | 125 | Meadowbrook (Rural) Grey VNA Matched Antenna | 2719' 829m | -131 / -11 | Drone | +| 2024-02-27 | ESP8266 @ 80MHz | TTGO Lora32 | SF8/CR48 | 125 | Meadowbrook (Rural) Grey VNA Matched Antenna | 2789' 850m | -138 / -13 | Drone | +| 2024-02-27 | ESP8266 @ 173MHz | TTGO Lora32 | SF7/CR48 | 125 | Meadowbrook (Rural) Grey VNA Matched Antenna | 2812' 857m | -131 / -8 | Drone | +| 2024-02-27 | ESP32-S2 + Bitenna | TTGO Lora32 | SF10/CR48 | 125 | Meadowbrook (Rural) (Note 1) | 3428' 1044m | -137 / -13 | Ground | +| 2024-02-27 | ESP32-S2 + Bitenna | TTGO Lora32 | SF10/CR48 | 125 | Meadowbrook (Rural) Light Precipitation | >4895' >1492m | -130 / -8 | Drone | +| 2024-02-27 | ESP32-S2 + Funtenna | TTGO Lora32 | SF10/CR48 | 125 | Meadow brook (Rural) Light Precipitation | 705' / 215m | -139 / -15 | Drone | +| 2024-02-27 | ESP32-S2 + Bitenna | TTGO Lora32 | SF10/CR48 | 125 | Snoqualmie Trail, Dog Park to Ribary Creek (Rural) Light Percipitation | 8460' / 2580m | -141 / -16 | Drone | + +1. There were two ground ESP32-S2 + Bitenna Tests. The one mentioned in the video is not recorded here, since I didn't get accurate results. +2. The bitenna ESP32-S2 test are done as a dipole antenna, connected to two different GPIOs, each set as the inversion of the other. +3. On the CH32V203, there is a 60 uA difference at 3.3V with anteanna on/off (some is going to be capacitive / inductive loading / reflected back because of SWR). The EIRP is **less** than this, based on the antenna stub SWR, but this is the total power consumption, so it is probably less than 120uW of EIRP. + + +## Resources + +### LoRa Software + * [The C++ Library I based my LoRa Frames On](https://github.com/myriadrf/LoRa-SDR) + * [A gnuradio LoRa library](https://github.com/tapparelj/gr-lora_sdr) + * [Another gnuradio LoRa library](https://github.com/rpp0/gr-lora) + * [GQRX](https://www.gqrx.dk/) + * [gnuradio](https://www.gnuradio.org/) + * [LoRa Baud Rate Calculator](https://unsigned.io/understanding-lora-parameters/) << be sure to select 125 or 500k Bandwidths, the default bandwidth is not useful. + +### Papers and other resources + * [A Great LoRa Introduction](https://medium.com/@prajzler/what-is-lora-the-fundamentals-79a5bb3e6dec) + * [A more grounded paper on LoRa](https://chrisye-liu.github.io/files/yang22emu.pdf) + * [Reversing LoRa by Matt Knight](https://github.com/matt-knight/research/blob/master/2016_05_20_jailbreak/Reversing-Lora-Knight.pdf) + * [An academic paper on LoRa](https://dl.acm.org/doi/10.1145/3546869) + +### Software Resources Directly Used + * [ch32v003fun](https://github.com/cnlohr/ch32v003fun) + * [esputil](https://github.com/cpq/esputil) dependency-free ESP programming + * [nosdk8266](github.com/cnlohr/nosdk8266) + +### Hardware + * [MikroTik LR9](https://mikrotik.com/product/wap_lr9_kit) + * [Airspy Mini SDR](https://v3.airspy.us/product/a-airspy-mini/) + * [LILYGO® T-Beam Meshtastic](https://www.lilygo.cc/products/t-beam-v1-1-esp32-lora-module) + +## Special Thanks + * @MustardTiger for a crazy amount of support work in this project + * Willmore for the editing work + * Several other folks in my discord for review work and editing work on this page + * My girlfriend for testing help and auxiliary camera work + * Everyone who helped out with my various open source projects + diff --git a/ch32v/ch32v003/Makefile b/ch32v/ch32v003/Makefile new file mode 100644 index 0000000..0bd2881 --- /dev/null +++ b/ch32v/ch32v003/Makefile @@ -0,0 +1,23 @@ +all : flash + +TARGET:=loratest +TARGET_MCU:=CH32V003 +CH32V003FUN:=../ch32v003fun/ch32v003fun + +EXTRA_ELF_DEPENDENCIES:=chirpbuff.h + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include ../ch32v003fun/ch32v003fun/ch32v003fun.mk + + +chirpbuff.h : rf_data_gen + ./rf_data_gen + +rf_data_gen : rf_data_gen.c + gcc -o $@ $^ -lm + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v003/README.md b/ch32v/ch32v003/README.md new file mode 100644 index 0000000..4e5add6 --- /dev/null +++ b/ch32v/ch32v003/README.md @@ -0,0 +1,7 @@ +# CH32V003 Firmware-Only 900MHz LoRa Transmitter + +This only barely works, and at short ranges. + +Be sure to provide a 24MHz clock (not crystal unless you disable the bypass) on PA1. + +Generally you cannot use the built-in oscillator circuit becuase it's too spread-y. diff --git a/ch32v/ch32v003/funconfig.h b/ch32v/ch32v003/funconfig.h new file mode 100644 index 0000000..a2baf88 --- /dev/null +++ b/ch32v/ch32v003/funconfig.h @@ -0,0 +1,9 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 1 +#define FUNCONF_USE_UARTPRINTF 0 + + +#endif + diff --git a/ch32v/ch32v003/loratest.c b/ch32v/ch32v003/loratest.c new file mode 100644 index 0000000..03db053 --- /dev/null +++ b/ch32v/ch32v003/loratest.c @@ -0,0 +1,440 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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. + +**/ + +// XXX WARNING: Something is wrong with this - +// The output isn't perfectly time aligned +// And as such there are extra images in weird places. +// TODO: Investigate the DMA+SPI Port jankyness. +#include "ch32v003fun.h" +#include +#include +#include "chirpbuff.h" +#include "chirpbuffinfo.h" + +#include "LoRa-SDR-Code.h" + +//#define LORAWAN +//#define TEST_TONE + +#ifdef LORAWAN +#include "lorawan_simple.h" +#endif + +#define SENDBUFF_WORDS (DMA_SIZE_WORDS*2) +uint16_t sendbuff[SENDBUFF_WORDS]; + +#if !defined( FOUND_PERFECT_DIVISOR ) +#error Code only written for perfect division right now. +#endif + +// Bits are shifted out MSBit first, then to LSBit + + +#define MAX_BYTES 25 +#define MAX_SYMBOLS (MAX_BYTES*2+16) + +// Our table is bespoke for the specific SF. +#define CHIPSSPREAD CHIRPLENGTH_WORDS// QUARTER_CHIRP_LENGTH_WORDS (TODO: Use the quater value elsewhere in the code) +#define MARK_FROM_SF0 (1<BSHR = 1; // Turn on GPIOD0 for profiling + + // Backup flags. + volatile int intfr = DMA1->INTFR; + do + { + // Clear all possible flags. + DMA1->INTFCR = DMA1_IT_GL3; + + + //int place = DMA1_Channel3->CNTR; + // CNTR says that there are THIS MANY bytes left in the transfer. + // So a high CNTR value indicates a very early place in the buffer. + + uint16_t * sb = 0; + + temp++; + + if( intfr & DMA1_IT_HT3 ) + { + sb = sendbuff; + } + else if( intfr & DMA1_IT_TC3 ) + { + sb = sendbuff + SENDBUFF_WORDS/2; + } + + if( sb ) + { + if( quadsetplace < 0 ) + { + // Abort Send + memset( sb, 0, SENDBUFF_WORDS*2/2 ); + DMA1_Channel3->CFGR &= ~DMA_CFGR1_EN; + goto complete; + } + + fxcycle += DMA_SIZE_WORDS; + if( fxcycle == NUM_DMAS_PER_QUARTER_CHIRP*DMA_SIZE_WORDS ) + { + fxcycle = 0; + // Advance to next quarter word. + quadsetplace++; + + if( quadsetplace > quadsetcount ) + { +#ifdef TEST_TONE + quadsetplace = 0; +#else + quadsetplace = -1; +#endif + memset( sb, 0, SENDBUFF_WORDS*2/2 ); + goto complete; + } + } + + int symbol = quadsets[quadsetplace]; // Actually 0...CHIRPLENGTHWORDS + + const uint16_t * tsb = 0; + + // Select down- or up-chirp. + if( symbol < 0 ) + { + int word = fxcycle - symbol - 1; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + word++; + tsb = (&chirpbuff[word+REVERSE_START_OFFSET_BYTES/4]); + } + else + { + int word = fxcycle + symbol; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + tsb = (&chirpbuff[word]); + } + + // I tried using the DMA to do the copy - but that didn't work for some reason. + //while( DMA1_Channel2->CFGR & 1 ); +// DMA1_Channel2->CNTR = DMA_SIZE_WORDS/2; +// DMA1_Channel2->MADDR = (uint32_t)tsb; +// DMA1_Channel2->PADDR = (uint32_t)sb; +// DMA1_Channel2->CFGR |= DMA_CFGR1_EN; + + int cpy = DMA_SIZE_WORDS/2; +#ifdef TEST_TONE + // Test tone + memset( sb, 0xaa, cpy*2 ); +#else +#if DMA_SIZE_WORDS_DIVISIBLE_BY_FOUR == 0 + #error need divisibiltiy by 2. +#else + //while( cpy-- ) { *(sb++) = wordo; } + // Guarantee aligned access. + uint32_t * sbw = (uint32_t*)(((uint32_t)sb)&~3); + uint32_t * tsbw = (uint32_t*)(((uint32_t)tsb)&~3); + //while( cpy-- ) { *(sbw++) = *(tsbw++); } + + // Align the data copy if needed + if( cpy & 1 ) + { + *(sbw++) = *(tsbw++); + } + cpy /= 2; // Doubled up per loop + asm volatile("\ +1:\ +c.lw a3, 0(%[from])\n\ +c.lw a4, 4(%[from])\n\ +c.addi %[from], 8\n\ +c.addi %[cpy], -1\n\ +c.sw a3, 0(%[to])\n\ +c.sw a4, 4(%[to])\n\ +c.addi %[to], 8\n\ +c.bnez %[cpy], 1b\n\ +" : [cpy]"+r"(cpy), [from]"+r"(tsbw), [to]"+r"(sbw) : : "a3", "a4", "memory"); +#endif +#endif + } + +complete: + intfr = DMA1->INTFR; + } while( intfr ); + + //GPIOD->BSHR = 1<<16; // Turn off GPIOD0 for profiling +} + + +int main() +{ + SystemInit(); + + funGpioInitAll(); + + // Set a wait state (1 = normal <= 48MHz) + FLASH->ACTLR = 1; + +// MCO for testing. +// funPinMode( PA8, GPIO_CFGLR_OUT_50Mhz_AF_PP ); RCC->CFGR0 |= RCC_CFGR0_MCO_PLL; + + printf( "Switching to HSE\n" ); + Delay_Ms( 10 ); + + // Disable clock security system. + RCC->CTLR &= ~RCC_CSSON; + + // Enable external crystal + RCC->CTLR |= RCC_HSEON; + + // XXX NOTE: This is only used if you have a clock, not an oscillator. +// RCC->CTLR |= RCC_HSEBYP; + + // Set System Clock Source to be 0. + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | 0; + + // Disable PLL + RCC->CTLR &= ~RCC_PLLON; + + // Switch to HSE + RCC->CFGR0 |= RCC_PLLSRC; + + // Enable PLL + RCC->CTLR |= RCC_PLLON; + + // Wait for HSE to become ready. + while( !( RCC->CTLR & RCC_HSERDY) ); + while( !( RCC->CTLR & RCC_PLLRDY) ); + + RCC->CFGR0 |= RCC_SW_1; // Switch system clock to PLL + printf( "HSE Switched\n" ); + Delay_Ms( 10 ); + RCC->CTLR &= ~RCC_HSION; + Delay_Ms( 10 ); + //printf( "HSI Off [%08lx %08lx]\n", RCC->CTLR, RCC->CFGR0 ); HSI Off [03035180 0001000a] + + funPinMode( PC6, GPIO_CFGLR_OUT_50Mhz_AF_PP ); // MOSI + + RCC->APB2PCENR |= RCC_APB2Periph_SPI1; + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + // Configure SPI + SPI1->CTLR1 = + SPI_NSS_Soft | SPI_CPHA_1Edge | SPI_CPOL_Low | SPI_DataSize_16b | + SPI_Mode_Master | SPI_Direction_1Line_Tx | + 0 | + (SPI_DIV-1)<<3; // Divisior = 0 + + + // If using DMA may need this. + SPI1->CTLR2 = SPI_CTLR2_TXDMAEN; + + SPI1->HSCR = 1; // High-speed enable. + + SPI1->CTLR1 |= CTLR1_SPE_Set; + //SPI1->DATAR = 0x55aa; // Set SPI line Low. + +#if 0 + // I tried using DMA Channel 4 to do a mem-mem copy. + // Doesn't seem to work. + DMA1_Channel2->PADDR = (uint32_t)sendbuff; // SOURCE + DMA1_Channel2->MADDR = (uint32_t)sendbuff; // DEST + DMA1_Channel2->CNTR = DMA_SIZE_WORDS; + DMA1_Channel2->CFGR = + DMA_M2M_Enable | + DMA_Priority_Low | + DMA_MemoryDataSize_HalfWord | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryInc_Enable | + DMA_PeripheralInc_Enable | + DMA_Mode_Normal | // DMA_Mode_Circular or DMA_Mode_Normal + DMA_DIR_PeripheralDST; +#endif + + //DMA1_Channel3 is for SPI1TX + DMA1_Channel3->PADDR = (uint32_t)&SPI1->DATAR; + DMA1_Channel3->MADDR = (uint32_t)sendbuff; + DMA1_Channel3->CNTR = 0;// sizeof( bufferset )/2; // Number of unique copies. (Don't start, yet!) + DMA1_Channel3->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_MemoryDataSize_HalfWord | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryInc_Enable | + DMA_Mode_Circular | // OR DMA_Mode_Circular or DMA_Mode_Normal + DMA_DIR_PeripheralDST | + DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. + + NVIC_EnableIRQ( DMA1_Channel3_IRQn ); + + memset( sendbuff, 0x00, sizeof( sendbuff ) ); + + + // Enter critical section. + DMA1_Channel3->MADDR = (uint32_t)sendbuff; + DMA1_Channel3->CNTR = SENDBUFF_WORDS; // Number of unique uint16_t entries. + DMA1_Channel3->CFGR |= DMA_CFGR1_EN; + + uint32_t frame = 0; + while(1) + { + Delay_Ms( 1000 ); + +#ifdef LORAWAN + // Optionally generate a LoRaWAN Packet. + const static uint8_t raw_pl[4] = { 0xaa, 0xaa, 0xaa, 0xaa, }; + // Just some random data. + static uint8_t raw_payload_with_b0[MAX_BYTES+8] = { 0 }; + uint8_t * payload_in = raw_payload_with_b0 + 16; + int payload_in_size; + + // Be sure to provide your appropriate keys and address here. + static const uint8_t payload_key[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // AppSKey Big Endian + static const uint8_t network_skey[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // NwkSKey Big Endian + static const uint8_t devaddress[4] = { 0x00, 0x00, 0x00, 0x00 }; // Device address Little Endian LSB (Written backwards from Device address default view) + + payload_in_size = GenerateLoRaWANPacket( raw_payload_with_b0, raw_pl, sizeof(raw_pl), payload_key, network_skey, devaddress, frame ); +#else + uint8_t payload_in[15] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + int payload_in_size = 15; + +#endif + + lora_symbols_count = 0; + int r = CreateMessageFromPayload( lora_symbols, &lora_symbols_count, MAX_SYMBOLS, SF_NUMBER, 4, payload_in, payload_in_size ); + + if( r < 0 ) + { + printf( "Failed to generate message (%d)\n", r ); + // Failed + continue; + } + + frame++; + + int j; + + quadsetcount = 0; + int16_t * qso = quadsets; + for( j = 0; j < PREAMBLE_CHIRPS; j++ ) + { + qso = AddChirp( qso, 0, 0 ); + } + + uint8_t syncword = 0x43; + + #if SF_NUMBER == 6 + #define CODEWORD_SHIFT 2 + #else + #define CODEWORD_SHIFT 3 + #endif + + if( CODEWORD_LENGTH > 0 ) + qso = AddChirp( qso, ( ( syncword & 0xf ) << CODEWORD_SHIFT ), 0 ); + if( CODEWORD_LENGTH > 1 ) + qso = AddChirp( qso, ( ( ( syncword & 0xf0 ) >> 4 ) << CODEWORD_SHIFT ), 0); + + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + + if( SF_NUMBER <= 6 ) + { + // Two additional upchirps with SF6 https://github.com/tapparelj/gr-lora_sdr/issues/74#issuecomment-1891569580 + for( j = 0; j < 2; j++ ) + qso = AddChirp( qso, 0, 0 ); + } + + for( j = 0; j < lora_symbols_count; j++ ) + { + int ofs = lora_symbols[j]; + qso = AddChirp( qso, ofs, 0 ); + } + + runningcount_bits = 0; + + // This tells the interrupt we have data. + quadsetcount = qso - quadsets + 0; + printf( "- %d -- %d [%d] %d; %d\n", (int)temp, (int)lora_symbols_count, (int)quadsetcount, CHIPSSPREAD/4, sendbuff[0] ); + quadsetplace = 0; + + DMA1_Channel3->CFGR |= DMA_CFGR1_EN; + + while( quadsetplace >= 0 ); + } +} + diff --git a/ch32v/ch32v003/rf_data_gen.c b/ch32v/ch32v003/rf_data_gen.c new file mode 100644 index 0000000..c75086e --- /dev/null +++ b/ch32v/ch32v003/rf_data_gen.c @@ -0,0 +1,58 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 + + +//#define KHZ500 + +#ifdef KHZ500 + +// Tested, works - be sure to set your radio to be able to receive this. +#define SF_NUMBER 10 +const double center_frequency = 904.6; +const double bw = .5; +#define SF_SYMBOL_TIME 0.00000025 +#else + +// Tested, works. +const double center_frequency = 904.5; +#define SF_NUMBER 8 +const double bw = .125; +#endif + +const uint32_t memory_offset = 0x00000; +#define SPI_DIV 2 +const double sample_rate = (48.0/2)/SPI_DIV; + + +#define ATTRIBUTE_FOR_DATA "__attribute__((section(\".text\"),aligned(32)))" +#define USE_16_BITS + +#include "../../lib/rf_data_gen.h" + +int main() +{ + return gen_buffer_files(); +} diff --git a/ch32v/ch32v003fun b/ch32v/ch32v003fun new file mode 160000 index 0000000..87e4ee5 --- /dev/null +++ b/ch32v/ch32v003fun @@ -0,0 +1 @@ +Subproject commit 87e4ee59d9f63e1c126c728adcbc68133361e57e diff --git a/ch32v/ch32v203/Makefile b/ch32v/ch32v203/Makefile new file mode 100644 index 0000000..62748fa --- /dev/null +++ b/ch32v/ch32v203/Makefile @@ -0,0 +1,23 @@ +all : flash + +TARGET:=loratest +TARGET_MCU:=CH32V203 +CH32V003FUN:=../ch32v003fun/ch32v003fun + +EXTRA_ELF_DEPENDENCIES:=chirpbuff.h + +EXTRA_CFLAGS:=-Wno-unused-function -I../../lib + +include ../ch32v003fun/ch32v003fun/ch32v003fun.mk + + +chirpbuff.h : rf_data_gen + ./rf_data_gen + +rf_data_gen : rf_data_gen.c + gcc -o $@ $^ -lm + +flash : cv_flash +clean : cv_clean + rm -rf rf_data_gen chirpbuff.dat chirpbuff.h chirpbuffinfo.h + diff --git a/ch32v/ch32v203/README.md b/ch32v/ch32v203/README.md new file mode 100644 index 0000000..238b657 --- /dev/null +++ b/ch32v/ch32v203/README.md @@ -0,0 +1,5 @@ +# CH32V203 example + +Flash this on a CH32V203 with a 8MHz external crystal, then connect a short length of wire to PB15. + +It will transmit SF8 Lora on 904.5MHz diff --git a/ch32v/ch32v203/funconfig.h b/ch32v/ch32v203/funconfig.h new file mode 100644 index 0000000..15aeb15 --- /dev/null +++ b/ch32v/ch32v203/funconfig.h @@ -0,0 +1,9 @@ +#ifndef _FUNCONFIG_H +#define _FUNCONFIG_H + +#define FUNCONF_USE_DEBUGPRINTF 0 +#define FUNCONF_USE_UARTPRINTF 1 + + +#endif + diff --git a/ch32v/ch32v203/loratest.c b/ch32v/ch32v203/loratest.c new file mode 100644 index 0000000..d657351 --- /dev/null +++ b/ch32v/ch32v203/loratest.c @@ -0,0 +1,441 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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 "ch32v003fun.h" +#include +#include +#include "chirpbuff.h" +#include "chirpbuffinfo.h" + +#include "../../lib/LoRa-SDR-Code.h" + +// NOTE: The SPI engine in the 203 isn't perfect, and I wasn't able to get the I2S engine working. + +// Optionally send LoRaWAN messages. Be sure to copy your keys from the things network. +#define LORAWAN + +#ifdef LORAWAN +#include "lorawan_simple.h" + static const uint8_t payload_key[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // AppSKey Big Endian + static const uint8_t network_skey[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // NwkSKey Big Endian + static const uint8_t devaddress[4] = { 0x00, 0x00, 0x00, 0x00 }; // Device address Little Endian LSB (Written backwards from Device address default view) +#endif + + +#define SENDBUFF_WORDS (DMA_SIZE_WORDS*2) +uint16_t sendbuff[SENDBUFF_WORDS]; + +#if !defined( FOUND_PERFECT_DIVISOR ) +#error Code only written for perfect division right now. +#endif + +// Bits are shifted out MSBit first, then to LSBit + + +#define MAX_BYTES 60 +#define MAX_SYMBOLS (MAX_BYTES*2+16) + +// Our table is bespoke for the specific SF. +#define CHIPSSPREAD CHIRPLENGTH_WORDS// QUARTER_CHIRP_LENGTH_WORDS (TODO: Use the quater value elsewhere in the code) +#define MARK_FROM_SF0 (1<BSHR = 1; // Turn on GPIOD0 for profiling + + // Backup flags. + volatile int intfr = DMA1->INTFR; + do + { + // Clear all possible flags. + DMA1->INTFCR = DMA1_IT_GL5; + + + int place = DMA1_Channel5->CNTR; + // CNTR says that there are THIS MANY bytes left in the transfer. + // So a high CNTR value indicates a very early place in the buffer. + + uint16_t * sb = 0; + + //if( intfr & DMA1_IT_HT5 ) + if( place < SENDBUFF_WORDS/2 ) + { + sb = sendbuff + SENDBUFF_WORDS/2; + } + //else if( intfr & DMA1_IT_TC5 ) + else + { + sb = sendbuff; + } + + if( sb ) + { + if( quadsetplace < 0 ) + { + // Abort Send + memset( sb, 0, SENDBUFF_WORDS*2/2 ); //in bytes, but only half the buffer. + DMA1_Channel5->CFGR &= ~DMA_Mode_Circular; // disable transfer. + goto complete; + } + + if( 0 ) // Generate test tone + { + int remain = SENDBUFF_WORDS/2; + do + { + uint16_t v = chirpbuff[quadsetplace++]; + if( quadsetplace >= QUARTER_CHIRP_LENGTH_WORDS*4 ) quadsetplace = 0; + *(sb++) = v; + } while( --remain ); + } + else + { + fxcycle += DMA_SIZE_WORDS; + if( fxcycle == NUM_DMAS_PER_QUARTER_CHIRP*DMA_SIZE_WORDS ) + { + fxcycle = 0; + // Advance to next quarter word. + quadsetplace++; + + if( quadsetplace > quadsetcount ) + { + quadsetplace = -1; + memset( sb, 0, SENDBUFF_WORDS*2/2 ); + goto complete; + } + } + + int symbol = quadsets[quadsetplace]; // Actually 0...CHIRPLENGTHWORDS + + const uint16_t * tsb = 0; + + // Select down- or up-chirp. + if( symbol < 0 ) + { + int word = fxcycle - symbol - 1; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + word++; + tsb = (&chirpbuff[word+REVERSE_START_OFFSET_BYTES/2]); + } + else + { + int word = fxcycle + symbol; + if( word >= CHIRPLENGTH_WORDS ) word -= CHIRPLENGTH_WORDS; + tsb = (&chirpbuff[word]); + } + + int cpy = DMA_SIZE_WORDS; + + // Very fast half-word-copy. + // Make sure the data is aligned to groups-of-two bytes. + if( cpy & 1 ) + { + *(sb++) = *(tsb++); + cpy--; + } + + cpy /= 2; // Doubled up per loop + + asm volatile("\ + 1:\ + lh a3, 0(%[from])\n\ + lh a4, 2(%[from])\n\ + c.addi %[from], 4\n\ + c.addi %[cpy], -1\n\ + sh a3, 0(%[to])\n\ + sh a4, 2(%[to])\n\ + c.addi %[to], 4\n\ + c.bnez %[cpy], 1b\n\ + " : [cpy]"+r"(cpy), [from]"+r"(tsb), [to]"+r"(sb) : : "a3", "a4", "memory"); + +// while( cpy-- ) { *(sb++) = *(tsb++); } // Doesn't help. GCC Still tries to use memcpy. + //memcpy( sb, tsb, DMA_SIZE_WORDS * 2 ); + } + } + +complete: + intfr = DMA1->INTFR; + } while( intfr ); + + //GPIOD->BSHR = 1<<16; // Turn off GPIOD0 for profiling +} + + +int main() +{ + SystemInit(); + + funGpioInitAll(); + + // Force HCLK to be nodiv. ch32vfun sets it to be a reasonbly high div. + RCC->CFGR0 &= ~RCC_PPRE1_DIV16; + +// MCO for testing. +// funPinMode( PA8, GPIO_CFGLR_OUT_50Mhz_AF_PP ); RCC->CFGR0 |= RCC_CFGR0_MCO_PLL; + + printf( "Switching to HSE\n" ); + Delay_Ms( 100 ); + + // Disable clock security system. + RCC->CTLR &= ~RCC_CSSON; + +#ifdef USE_EXTERNAL_CLOCK + // No crystal - use clock. + RCC->CTLR |= RCC_HSEBYP; +#endif + + // Enable external crystal + RCC->CTLR |= RCC_HSEON; + + // Set System Clock Source to be 0. + RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | 0; + + // Disable PLL + RCC->CTLR &= ~RCC_PLLON; + + +#ifdef USE_EXTERNAL_CLOCK + // Set PLL to 9x not 18x + RCC->CFGR0 = ( RCC->CFGR0 & ~RCC_PLLMULL18 ) | RCC_PLLMULL9; +#endif + + // Switch to HSE + RCC->CFGR0 |= RCC_PLLSRC; + + // Enable PLL + RCC->CTLR |= RCC_PLLON; + + // Wait for HSE to become ready. + while( !( RCC->CTLR & RCC_HSERDY) ); + while( !( RCC->CTLR & RCC_PLLRDY) ); + RCC->CFGR0 |= RCC_SW_1; // Switch system clock to PLL + printf( "HSE Switched\n" ); + Delay_Ms( 10 ); + RCC->CTLR &= ~RCC_HSION; + Delay_Ms( 10 ); + printf( "HSI Off [%08lx %08lx]\n", RCC->CTLR, RCC->CFGR0 ); + +// funPinMode( PB12, GPIO_CFGLR_OUT_50Mhz_AF_PP ); // NSS +// funPinMode( PB13, GPIO_CFGLR_OUT_50Mhz_AF_PP ); // SCK +// funPinMode( PB14, GPIO_CFGLR_OUT_50Mhz_AF_PP ); // MISO + funPinMode( PB15, GPIO_CFGLR_OUT_50Mhz_AF_PP ); // MOSI + + RCC->APB1PRSTR = RCC_SPI2RST; + RCC->APB1PRSTR = 0; + RCC->APB1PCENR |= RCC_APB1Periph_SPI2; + RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; + + // Configure SPI + SPI2->CTLR1 = + SPI_NSS_Soft | SPI_CPHA_1Edge | SPI_CPOL_Low | SPI_DataSize_16b | + SPI_Mode_Master | SPI_Direction_1Line_Tx | + 0 | + 0<<3; // Divisior = 0 + + // If using DMA may need this. + SPI2->CTLR2 = SPI_CTLR2_TXDMAEN; + + + SPI2->HSCR = 1; // High-speed enable. + + SPI2->CTLR1 |= CTLR1_SPE_Set; + //SPI2->DATAR = 0x55aa; // Set SPI line Low. + + //DMA1_Channel5 is for SPI2TX + DMA1_Channel5->PADDR = (uint32_t)&SPI2->DATAR; + DMA1_Channel5->MADDR = (uint32_t)sendbuff; + DMA1_Channel5->CNTR = 0;// sizeof( bufferset )/2; // Number of unique copies. (Don't start, yet!) + DMA1_Channel5->CFGR = + DMA_M2M_Disable | + DMA_Priority_VeryHigh | + DMA_MemoryDataSize_HalfWord | + DMA_PeripheralDataSize_HalfWord | + DMA_MemoryInc_Enable | + DMA_Mode_Normal | // OR DMA_Mode_Circular or DMA_Mode_Normal + DMA_DIR_PeripheralDST | + DMA_IT_TC | DMA_IT_HT; // Transmission Complete + Half Empty Interrupts. + + NVIC_EnableIRQ( DMA1_Channel5_IRQn ); + DMA1_Channel5->CFGR |= DMA_CFGR1_EN; + + + memset( sendbuff, 0x00, sizeof( sendbuff ) ); + + // Enter critical section. + DMA1_Channel5->CNTR = 0; + DMA1_Channel5->MADDR = (uint32_t)sendbuff; + DMA1_Channel5->CNTR = SENDBUFF_WORDS; // Number of unique uint16_t entries. + DMA1_Channel5->CFGR |= DMA_Mode_Circular; + + uint16_t lora_symbols[MAX_SYMBOLS]; + int lora_symbols_count; + + while(1) + { + + Delay_Ms( 1000 ); + + +#ifdef LORAWAN + Delay_Ms( 1000 ); + static uint32_t frame = 0; + + // Send a message with LoraWan. Formatted specifically for thethings.network. + uint8_t inner_payload_raw[24]; + int inner_payload_len = snprintf( (char*)inner_payload_raw, 24, "meow%lu ", frame%10 ); + inner_payload_len = 5; + + // Just some random data. + uint8_t raw_payload_with_b0[259+8] = { }; + uint8_t * payload_in = raw_payload_with_b0 + 16; + uint8_t * pl = payload_in; + int payload_in_size = 0; + + pl += GenerateLoRaWANPacket( raw_payload_with_b0, inner_payload_raw, inner_payload_len, payload_key, network_skey, devaddress, frame++); + + payload_in_size = pl - payload_in; + + lora_symbols_count = 0; +#else + + // Just some random data. + uint8_t payload_in[MAX_BYTES] = { 0xbb, 0xcc, 0xde, 0x55, 0x22,}; + int payload_in_size = 6; + + static int msgno = 0; + payload_in[4] = msgno++; + + +#endif + + lora_symbols_count = 0; + int r = CreateMessageFromPayload( lora_symbols, &lora_symbols_count, MAX_SYMBOLS, SF_NUMBER, 4, payload_in, payload_in_size ); + + if( r < 0 ) + { + printf( "Failed to generate message (%d)\n", r ); + // Failed + continue; + } + + int j; + + quadsetcount = 0; + int16_t * qso = quadsets; + for( j = 0; j < PREAMBLE_CHIRPS; j++ ) + { + qso = AddChirp( qso, 0, 0 ); + } + + uint8_t syncword = 0x43; + + #define CODEWORD_SHIFT 3 + + if( CODEWORD_LENGTH > 0 ) + qso = AddChirp( qso, ( ( syncword & 0xf ) << CODEWORD_SHIFT ), 0 ); + if( CODEWORD_LENGTH > 1 ) + qso = AddChirp( qso, ( ( ( syncword & 0xf0 ) >> 4 ) << CODEWORD_SHIFT ), 0); + + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + + if( SF_NUMBER <= 6 ) + { + // Two additional upchirps with SF6 https://github.com/tapparelj/gr-lora_sdr/issues/74#issuecomment-1891569580 + for( j = 0; j < 2; j++ ) + qso = AddChirp( qso, 0, 0 ); + } + + for( j = 0; j < lora_symbols_count; j++ ) + { + int ofs = lora_symbols[j]; + //ofs = ofs ^ ((MARK_FROM_SF6<<6) -1); + //ofs &= (MARK_FROM_SF6<<6) -1; + qso = AddChirp( qso, ofs, 0 ); + printf( "%03x ", ofs ); + } + printf( "\n" ); + + runningcount_bits = 0; + + // This tells the interrupt we have data. + quadsetcount = qso - quadsets + 0; + printf( "--- %d [%d] %d\n", (int)lora_symbols_count, (int)quadsetcount, CHIPSSPREAD/4 ); + + quadsetplace = 0; + + DMA1_Channel5->CFGR |= DMA_Mode_Circular; + } +} + diff --git a/ch32v/ch32v203/rf_data_gen.c b/ch32v/ch32v203/rf_data_gen.c new file mode 100644 index 0000000..9e54015 --- /dev/null +++ b/ch32v/ch32v203/rf_data_gen.c @@ -0,0 +1,91 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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. +*/ + +// TEST 1: 125kHz with -.028 675 +// TEST 2: 500kHz with 138 kHz correction. 534?? +// TEST 3: 500kHz with 0 kHz correction. FAIL +// TEST 4: 125kHz with -.028 5V 1210 + +//END OF RED ANTENNA + +// TEST 5: 125kHz with -.027 3.3V, shorter antenna? 829 + +// TEST 6: 125k ESP 80 GREY antenna ???/??? 850 / + +#include + +// Transmit a 500kHz width LoRa +//#define KHZ500 + +// Expects a 24MHz external clock. +//#define USE_EXTERNAL_CLOCK + +#ifdef KHZ500 + + const double tune_mhz = -0.000; + const double center_frequency = 904.6 + tune_mhz; + const double bw = .5; + #ifdef USE_EXTERNAL_CLOCK + #define SF_NUMBER 9 + #else + #define SF_NUMBER 10 + #endif + #define SF_SYMBOL_TIME 0.00000025 + +#else // 125kHz channel + + const double bw = 0.125; + + #ifdef USE_EXTERNAL_CLOCK + const double tune_mhz = 0.00; + #define SF_NUMBER 7 + #else + const double tune_mhz = -0.028; //XXX ??? Per device tuning? Or area the load caps just wrong? + #define SF_NUMBER 8 + #endif + + const double center_frequency = 904.5 + tune_mhz; + +#endif + +#define SPI_DIV 1 + + +#ifdef USE_EXTERNAL_CLOCK +const double sample_rate = (24*9/2)/SPI_DIV; //216MHz PLL +#else +const double sample_rate = (72)/SPI_DIV; +#endif + +#define ATTRIBUTE_FOR_DATA "__attribute__((section(\".text\")))" +#define USE_16_BITS + +const uint32_t memory_offset = 0x00000; + +#include "../../lib/rf_data_gen.h" + +int main() +{ + return gen_buffer_files(); +} diff --git a/esp32s2/loratest/.gitignore b/esp32s2/loratest/.gitignore new file mode 100644 index 0000000..af96791 --- /dev/null +++ b/esp32s2/loratest/.gitignore @@ -0,0 +1,2 @@ +.vscode +build diff --git a/esp32s2/loratest/CMakeLists.txt b/esp32s2/loratest/CMakeLists.txt new file mode 100644 index 0000000..b0a72d1 --- /dev/null +++ b/esp32s2/loratest/CMakeLists.txt @@ -0,0 +1,23 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + + +add_custom_target(stub_bootload + # If the swadge is running reboot it into the bootloader. + COMMAND make -C ../tools/reboot_into_bootloader reboot + COMMAND sleep 0.5 +) +#add_dependencies(flash before_flash) +add_custom_target(stub_run + #Sometimes the swadge needs a kick to get rebooted + COMMAND sleep 0.5 + COMMAND esptool.py --before no_reset --after no_reset load_ram ../tools/bootload_reboot_stub/bootload_reboot_stub.bin +) + + +project(usb_sandbox) + + diff --git a/esp32s2/loratest/main/CMakeLists.txt b/esp32s2/loratest/main/CMakeLists.txt new file mode 100644 index 0000000..9387585 --- /dev/null +++ b/esp32s2/loratest/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "main.c" "app.c" + INCLUDE_DIRS "" ) + + diff --git a/esp32s2/loratest/main/app.c b/esp32s2/loratest/main/app.c new file mode 100644 index 0000000..5dc3fae --- /dev/null +++ b/esp32s2/loratest/main/app.c @@ -0,0 +1,454 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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 "esp_system.h" +#include "hal/gpio_types.h" +#include "esp_log.h" +#include "soc/efuse_reg.h" +#include "soc/soc.h" +#include "soc/system_reg.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "soc/gpio_sig_map.h" + + +#include "soc/io_mux_reg.h" +#include "soc/dedic_gpio_reg.h" + +// Funtenna will output on GPIO1 and 14. Otherwise it will be 17 and 18 +//#define FUNTENNA + +int global_i = 100; + + +static inline uint32_t getCycleCount() +{ + uint32_t ccount; + asm volatile("rsr %0,ccount":"=a" (ccount)); + return ccount; +} + + +#define IO_MUX_REG(x) XIO_MUX_REG(x) +#define XIO_MUX_REG(x) IO_MUX_GPIO##x##_REG + +#define GPIO_NUM(x) XGPIO_NUM(x) +#define XGPIO_NUM(x) GPIO_NUM_##x + + +#ifdef FUNTENNA + +#define RF1_PIN 1 +#define RF2_PIN 14 +#else +#define RF1_PIN 17 +#define RF2_PIN 18 +#endif + + + +#include "hal/gpio_types.h" +#include "driver/gpio.h" +#include "rom/gpio.h" +#include "soc/i2s_reg.h" +#include "soc/periph_defs.h" +#include "rom/lldesc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc.h" +#include "soc/regi2c_apll.h" +//#include "components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h +#include "hal/regi2c_ctrl_ll.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/regi2c_ctrl.h" +#include "hal/clk_tree_ll.h" + +#include "siggen.h" + + + + +#define I2C_RTC_WIFI_CLK_EN (SYSCON_WIFI_CLK_EN_REG) + +#define I2C_RTC_CLK_GATE_EN (BIT(18)) +#define I2C_RTC_CLK_GATE_EN_M (BIT(18)) +#define I2C_RTC_CLK_GATE_EN_V 0x1 +#define I2C_RTC_CLK_GATE_EN_S 18 + +#define I2C_RTC_CONFIG0 0x6000e048 + +#define I2C_RTC_MAGIC_CTRL 0x00001FFF +#define I2C_RTC_MAGIC_CTRL_M ((I2C_RTC_MAGIC_CTRL_V)<<(I2C_RTC_MAGIC_CTRL_S)) +#define I2C_RTC_MAGIC_CTRL_V 0x1FFF +#define I2C_RTC_MAGIC_CTRL_S 4 + +#define I2C_RTC_CONFIG1 0x6000e044 + +#define I2C_RTC_BOD_MASK (BIT(22)) +#define I2C_RTC_BOD_MASK_M (BIT(22)) +#define I2C_RTC_BOD_MASK_V 0x1 +#define I2C_RTC_BOD_MASK_S 22 + +#define I2C_RTC_SAR_MASK (BIT(18)) +#define I2C_RTC_SAR_MASK_M (BIT(18)) +#define I2C_RTC_SAR_MASK_V 0x1 +#define I2C_RTC_SAR_MASK_S 18 + +#define I2C_RTC_BBPLL_MASK (BIT(17)) +#define I2C_RTC_BBPLL_MASK_M (BIT(17)) +#define I2C_RTC_BBPLL_MASK_V 0x1 +#define I2C_RTC_BBPLL_MASK_S 17 + +#define I2C_RTC_APLL_MASK (BIT(14)) +#define I2C_RTC_APLL_MASK_M (BIT(14)) +#define I2C_RTC_APLL_MASK_V 0x1 +#define I2C_RTC_APLL_MASK_S 14 + +#define I2C_RTC_ALL_MASK 0x00007FFF +#define I2C_RTC_ALL_MASK_M ((I2C_RTC_ALL_MASK_V)<<(I2C_RTC_ALL_MASK_S)) +#define I2C_RTC_ALL_MASK_V 0x7FFF +#define I2C_RTC_ALL_MASK_S 8 + +#define I2C_RTC_CONFIG2 0x6000e000 + +#define I2C_RTC_BUSY (BIT(25)) +#define I2C_RTC_BUSY_M (BIT(25)) +#define I2C_RTC_BUSY_V 0x1 +#define I2C_RTC_BUSY_S 25 + +#define I2C_RTC_WR_CNTL (BIT(24)) +#define I2C_RTC_WR_CNTL_M (BIT(24)) +#define I2C_RTC_WR_CNTL_V 0x1 +#define I2C_RTC_WR_CNTL_S 24 + +#define I2C_RTC_DATA 0x000000FF +#define I2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S)) +#define I2C_RTC_DATA_V 0xFF +#define I2C_RTC_DATA_S 16 + +#define I2C_RTC_ADDR 0x000000FF +#define I2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S)) +#define I2C_RTC_ADDR_V 0xFF +#define I2C_RTC_ADDR_S 8 + +#define I2C_RTC_SLAVE_ID 0x000000FF +#define I2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S)) +#define I2C_RTC_SLAVE_ID_V 0xFF +#define I2C_RTC_SLAVE_ID_S 0 + +#define I2C_RTC_MAGIC_DEFAULT (0x1c40) + +#define I2C_BOD 0x61 +#define I2C_BBPLL 0x66 +#define I2C_SAR_ADC 0X69 +#define I2C_APLL 0X6D + + +int lastend = 0; + +// Configures APLL = 480 / 4 = 120 +// 40 * (SDM2 + SDM1/(2^8) + SDM0/(2^16) + 4) / ( 2 * (ODIV+2) ); +// Datasheet recommends that numerator does not exceed 500MHz. +void IRAM_ATTR local_rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div) +{ + REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1); + REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0); + + if (enable) { + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1); + REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_1); + REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_2_REV1); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div ); + } + + + // Settings determined experimentally. + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_TSCHGP, 0 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_EN_FAST_CAL, 1 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DHREF_SEL, 0 ); // 0..3 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DLREF_SEL, 0 ); // 0..3 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_SDM_DITHER, 1 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DVDD, 25 ); // 0 .. 31 + +} + + +void IRAM_ATTR regi2c_write_reg_raw_local(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +{ + uint32_t temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S) + | ((reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S) + | ((0x1 & I2C_RTC_WR_CNTL_V) << I2C_RTC_WR_CNTL_S) + | (((uint32_t)data & I2C_RTC_DATA_V) << I2C_RTC_DATA_S); + while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY)); + REG_WRITE(I2C_RTC_CONFIG2, temp); +} + + +void apll_quick_update( uint32_t sdm ) +{ + uint8_t sdm2 = sdm>>16; + uint8_t sdm1 = (sdm>>8)&0xff; + uint8_t sdm0 = (sdm>>0)&0xff; + static int last_sdm_0 = -1; + static int last_sdm_1 = -1; + static int last_sdm_2 = -1; + + if( sdm2 != last_sdm_2 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM2, sdm2); + if( sdm0 != last_sdm_0 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM0, sdm0); + if( sdm1 != last_sdm_1 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM1, sdm1); + + last_sdm_2 = sdm2; + last_sdm_1 = sdm1; + last_sdm_0 = sdm0; +} + + + +void sandbox_main() +{ + printf( "sandbox_main()\n" ); + + + + DPORT_SET_PERI_REG_MASK( DPORT_CPU_PERI_CLK_EN_REG, DPORT_CLK_EN_DEDICATED_GPIO ); + DPORT_CLEAR_PERI_REG_MASK( DPORT_CPU_PERI_RST_EN_REG, DPORT_RST_EN_DEDICATED_GPIO); + + // Setup GPIO39 to be the PRO ALONE output (For LEDs) + REG_WRITE( GPIO_OUT1_W1TC_REG, 1<<(39-32) ); + REG_WRITE( GPIO_ENABLE1_W1TS_REG, 1<<(39-32) ); + REG_WRITE( IO_MUX_GPIO39_REG, 2< 0 ) + uprintf( "%d %d\n", (int)sdm, (int)fplv ); + } +//EnableISR(); +#else + + uint32_t start = getCycleCount(); + frame = (start) % 24000000; + int do_send = false; + if( (uint32_t)(start - lastend) > 240000000 ) + { + do_send = true; + } + + { + int spin; + + gpio_matrix_out( 39, PRO_ALONEGPIO_OUT0_IDX, 0, 0 ); + gpio_set_drive_capability( 39, GPIO_DRIVE_CAP_3 ); + + // Create an RGB Rainbow value + uint32_t ws_out = 0xff00ff;//do_send? 0 : 0xff; + + #define nop __asm__ __volatile__("nop\n") + int i; + // Shift out all 24 bits, note the 1 and 3 for timing is baesed off an XTAL clock. + for( i = 0; i < 24; i++ ) + { + __asm__ __volatile__ ("set_bit_gpio_out 0x1"); + + int high_for = ( ws_out & 0x800000 )?3:1; + for( spin = 0; spin < high_for; spin++ ) nop; + + __asm__ __volatile__ ("clr_bit_gpio_out 0x1"); + int low_for = ( ws_out & 0x800000 )?1:3; + for( spin = 0; spin < low_for; spin++ ) nop; + + ws_out<<=1; + } + esp_rom_delay_us( 5000 ); + + } + + if( do_send ) + { + SigSetupTest(); + int iterct = 0; + int dither = 0; + + gpio_matrix_out( GPIO_NUM(RF1_PIN), CLK_I2S_MUX_IDX, 1, 0 ); + gpio_matrix_out( GPIO_NUM(RF2_PIN), CLK_I2S_MUX_IDX, 0, 0 ); + //REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, 0); + //REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, 1); + + //DisableISR(); + while(1) + { + int fplv = 0; + // Send every second + // If you want to dialate time, do it here. + frame = (getCycleCount()) - start; + fplv = SigGen( frame, sdmBaseTarget ); + + + //XXX TODO: Experiment more with dither. It doesn't appear to have an immediate effect? + //dither = ( dither + sdmDivisor/4) % sdmDivisor; + uint32_t sdm = sdmBaseTarget + ( fplv + dither ) / sdmDivisor; + + if( fplv < 0 ) break; + apll_quick_update( sdm ); + iterct++; + } + //EnableISR(); + //REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, 0); + //REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, 1); + + gpio_matrix_out( GPIO_NUM(RF1_PIN), CLK_I2S_MUX_IDX, 1, 1 ); + gpio_matrix_out( GPIO_NUM(RF2_PIN), CLK_I2S_MUX_IDX, 0, 1 ); + + printf( "Iter: %d\n", iterct ); + lastend = getCycleCount(); + } +#endif + +// vTaskDelay( 1 ); +} + +struct SandboxStruct +{ + void (*fnIdle)(); +}; +struct SandboxStruct sandbox_mode = +{ + .fnIdle = sandbox_tick, +}; diff --git a/esp32s2/loratest/main/main.c b/esp32s2/loratest/main/main.c new file mode 100644 index 0000000..647de92 --- /dev/null +++ b/esp32s2/loratest/main/main.c @@ -0,0 +1,94 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "spi_flash_mmap.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" // or "esp_efuse_custom_table.h" +#include "esp_task_wdt.h" +#include "esp_log.h" +#include "soc/dedic_gpio_reg.h" +#include "driver/gpio.h" +#include "soc/soc.h" +#include "soc/system_reg.h" +#include "soc/usb_reg.h" +#include "ulp_riscv.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "rom/gpio.h" +#include "soc/rtc.h" + +#define SOC_DPORT_USB_BASE 0x60080000 + +struct SandboxStruct +{ + void (*fnIdle)(); +}; + + +struct SandboxStruct * g_SandboxStruct; + + +void esp_sleep_enable_timer_wakeup(); + +volatile void * keep_symbols[] = { 0, vTaskDelay, ulp_riscv_halt, + ulp_riscv_timer_resume, ulp_riscv_timer_stop, ulp_riscv_load_binary, + ulp_riscv_run, ulp_riscv_config_and_run, esp_sleep_enable_timer_wakeup, + ulp_set_wakeup_period, rtc_gpio_init, rtc_gpio_set_direction, + rtc_gpio_set_level, gpio_config, gpio_matrix_out, gpio_matrix_in, + rtc_clk_cpu_freq_get_config, rtc_clk_cpu_freq_set_config_fast, + rtc_clk_apb_freq_get }; + +extern struct SandboxStruct sandbox_mode; + +void app_main(void) +{ + printf("Hello world! Keep table at %p\n", &keep_symbols ); + + g_SandboxStruct = &sandbox_mode; + + // esp_efuse_set_rom_log_scheme(ESP_EFUSE_ROM_LOG_ALWAYS_OFF); + esp_efuse_set_rom_log_scheme(ESP_EFUSE_ROM_LOG_ALWAYS_ON); + + printf("Minimum free heap size: %d bytes\n", (int)esp_get_minimum_free_heap_size()); + + void sandbox_main(); + + sandbox_main(); + + do + { + if( g_SandboxStruct && g_SandboxStruct->fnIdle ) { g_SandboxStruct->fnIdle(); } + esp_task_wdt_reset(); + taskYIELD(); + } while( 1 ); + +// printf("Restarting now.\n"); +// fflush(stdout); +// esp_restart(); +} diff --git a/esp32s2/loratest/main/siggen.h b/esp32s2/loratest/main/siggen.h new file mode 100644 index 0000000..e03109d --- /dev/null +++ b/esp32s2/loratest/main/siggen.h @@ -0,0 +1,287 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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. + +**/ + + +#ifndef _SIGGEN_H +#define _SIGGEN_H + +#include +#include "../../../lib/LoRa-SDR-Code.h" + +#define SF_NUMBER 10 + +// This is MEGA overkill. No way would we ever use them all. +#define MAX_SYMBOLS 2070 + +// https://electronics.stackexchange.com/questions/278192/understanding-the-relationship-between-lora-chips-chirps-symbols-and-bits +// Has some good hints + +// At 125kHz +// https://medium.com/@prajzler/what-is-lora-the-fundamentals-79a5bb3e6dec +// With SF5, You get 3906 chips/second "Symbol Rate" (Included to help with math division) +// With SF7, You get 976 chips/second / 5469 bits/sec + +// 7 bits per symbol (I think) +// 7 * 4/5 = 5.6 data bits per symbol. +// https://wirelesspi.com/understanding-lora-phy-long-range-physical-layer/ says 7 for SF7 + +#define MARK_FROM_SF0 (1<= 11 + #define CODEWORD_SHIFT 5 // XXX TODO: Unknown for SF11, SF12 Might be 3? +#else + #define CODEWORD_SHIFT 3 +#endif + + if( CODEWORD_LENGTH > 0 ) + qso = AddChirp( qso, ( ( syncword & 0xf ) << CODEWORD_SHIFT ), 0 ); + if( CODEWORD_LENGTH > 1 ) + qso = AddChirp( qso, ( ( ( syncword & 0xf0 ) >> 4 ) << CODEWORD_SHIFT ), 0 ); + + + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + + if( SF_NUMBER <= 6 ) + { + // Two additional upchirps with SF6 https://github.com/tapparelj/gr-lora_sdr/issues/74#issuecomment-1891569580 + for( j = 0; j < 2; j++ ) + { + qso = AddChirp( qso, 0, 0 ); + } + } + + for( j = 0; j < symbols_len; j++ ) + { + int ofs = symbols[j]; + //ofs = ofs ^ ((MARK_FROM_SF6<<6) -1); + //ofs &= (MARK_FROM_SF6<<6) -1; + qso = AddChirp( qso, ofs, 0 ); + } + + quadsetcount = qso - quadsets; +// printf( "--- %d %d %d\n", symbols_len, quadsetcount, CHIPSSPREAD/4 ); +} + +static int32_t SigGen( uint32_t Frame240MHz, uint32_t codeTarg ) +{ + // TODO: Get some of these encode things going: https://github.com/myriadrf/LoRa-SDR/blob/master/LoRaCodes.hpp + + // frame = 0...240000000 + uint32_t sectionQuarterNumber = Frame240MHz / (CHIPSSPREAD/4); + if( sectionQuarterNumber >= quadsetcount ) + return -codeTarg; + + int32_t quadValue = quadsets[sectionQuarterNumber]; + uint32_t placeInQuad = Frame240MHz % (CHIPSSPREAD/4); + + if( quadValue >= 0 ) + return ( ( quadValue + placeInQuad ) % CHIPSSPREAD); // Up-Chirp + else + return ( ( quadValue - placeInQuad + CHIPSSPREAD ) % CHIPSSPREAD ); // Down-Chirp + +#if 0 + // Let's say 1ms per sweep. + int32_t sectionQuarterNumber = Frame240MHz / (CHIPSSPREAD/4); + uint32_t placeInSweep = Frame240MHz % CHIPSSPREAD; + // 2400 edge-to-edge = + if( sectionQuarterNumber < 0 ) return -codeTarg; + + sectionQuarterNumber -= PREAMBLE_CHIRPS*4; + + // Preamble Start + if( sectionQuarterNumber < 0 ) + { + return ((placeInSweep /*+ 240000/2*/) % CHIPSSPREAD) / DESPREAD; + } + + // Last 2 codes here are for the sync word. + +#define SYNC_WORD +#ifdef SYNC_WORD + // https://static1.squarespace.com/static/54cecce7e4b054df1848b5f9/t/57489e6e07eaa0105215dc6c/1464376943218/Reversing-Lora-Knight.pdf + // Says that this does not exist. but, it does seem to exist in some of their waterfalls. + sectionQuarterNumber -= 4*2; + // Two symbols + if( sectionQuarterNumber < 0 ) + { + int32_t chirp = (8+sectionQuarterNumber)/4; + uint32_t SYNCWORD = (((0x34)>>(4-chirp*4)) & 0xf)<<3; //0x34 for some vendors? + int32_t offset = SYNCWORD * CHIPSSPREAD / (MARK_FROM_SF7*128); + return (( placeInSweep + offset) % CHIPSSPREAD) / DESPREAD; + } +#endif +/* + + EXTRA NOTES: lora-grc says to look for sync word 18 +*/ + + + + sectionQuarterNumber -= 9; + + if( sectionQuarterNumber < 0 ) + { + // Down-Sweeps for Sync + return ((CHIPSSPREAD-placeInSweep/*+240000/2*/) % CHIPSSPREAD) / DESPREAD; + } + + uint32_t chirp = (sectionQuarterNumber)/4; + if( chirp < symbols_len ) + { + placeInSweep += (CHIPSSPREAD*3/4); + uint32_t offset = ( symbols[chirp] + 0 ) * CHIPSSPREAD / (MARK_FROM_SF7*128); + fplv = ((placeInSweep + offset) % CHIPSSPREAD) / DESPREAD; + return fplv; + } + else + { + return -codeTarg; + //return -1; + } +#endif +} + +/* + A real semtech SX1276 will produce 16 symbols at SF8 if + Given 2 byte payload, CRC explicit header. + Given 3 bytes of payload, that goes up to 24 symbols. + + [HEADER] [HEADER*0.5] [HEADER] **An extra byte** [PAYLOAD] [PAYLOAD] [PAYLOAD] [CRC] [CRC] << Does not fit. + + Payload sizes: + -5 would be 8 (Considering CRC would be -3 bytes) + -4 would be 8 + -3 would be 8 + -2 would be 8 + -1 would be 16 + 0 would be 16 + 1 byte: 16 symbols. (Include CRC so 3 bytes) + 2 byte: 16 symbols. (Include CRC so 4 bytes) + // theoreteically, 2 bytes + 2 crc should fit nicely into 16 symbols (or 8 bytes) BUT 3+2 (5) does not. + + 3 byte: 24 symbols. (Include CRC so 5 bytes) + 4 byte: 24 symbols + 5 byte: 24 symbols. + 6 byte: 24 symbols. + 7 byte: 32 symbols. + 8 byte: 32 symbols. + 9 byte: 32 symbols. + 10 byte: 32 symbols. + 11 byte: 40 symbols. + + That means there's + +*/ + +#endif + diff --git a/esp32s2/loratest/partitions.csv b/esp32s2/loratest/partitions.csv new file mode 100644 index 0000000..209e1e3 --- /dev/null +++ b/esp32s2/loratest/partitions.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +# Note: if you change the size of the nvs partition, make sure to update NVS_PARTITION_SIZE in `components/hdw-nvs/nvs_manager.h` +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +storage, data, spiffs, , 0xF0000, diff --git a/esp32s2/loratest/sdkconfig b/esp32s2/loratest/sdkconfig new file mode 100644 index 0000000..2645b80 --- /dev/null +++ b/esp32s2/loratest/sdkconfig @@ -0,0 +1,1810 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.1.1 Project Configuration +# +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_CP_DMA_SUPPORTED=y +CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SUPPORTS_SECURE_DL_MODE=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_RISCV_COPROC_SUPPORTED=y +CONFIG_SOC_USB_OTG_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED=y +CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD=y +CONFIG_SOC_TEMP_SENSOR_SUPPORTED=y +CONFIG_SOC_CACHE_SUPPORT_WRAP=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_PSRAM_DMA_CAPABLE=y +CONFIG_SOC_XT_WDT_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SYSTIMER_SUPPORTED=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_HMAC_SUPPORTED=y +CONFIG_SOC_DIG_SIGN_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_MEMPROT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_ARBITER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED=y +CONFIG_SOC_ADC_MONITOR_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=32 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_IIR_FILTER_NUM=2 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=83333 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=611 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=13 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=13 +CONFIG_SOC_ADC_CALIBRATION_V1_SUPPORTED=y +CONFIG_SOC_ADC_SELF_HW_CALI_SUPPORTED=y +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y +CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED=y +CONFIG_SOC_CP_DMA_MAX_BUFFER_SIZE=4095 +CONFIG_SOC_CPU_CORES_NUM=1 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=47 +CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER=y +CONFIG_SOC_GPIO_FILTER_CLK_SUPPORT_APB=y +CONFIG_SOC_GPIO_SUPPORT_RTC_INDEPENDENT=y +CONFIG_SOC_GPIO_SUPPORT_FORCE_HOLD=y +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0x7FFFFFFFFFFF +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x00007FFFFC000000 +CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_ALLOW_REG_ACCESS=y +CONFIG_SOC_DEDIC_GPIO_HAS_INTERRUPT=y +CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_HW_CLR_BUS=y +CONFIG_SOC_I2C_SUPPORT_REF_TICK=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2S_NUM=1 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_DMA_EQUAL=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_APLL_MIN_FREQ=250000000 +CONFIG_SOC_I2S_APLL_MAX_FREQ=500000000 +CONFIG_SOC_I2S_APLL_MIN_RATE=10675 +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=1 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 +CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=5 +CONFIG_SOC_MMU_PERIPH_NUM=1 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=4 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=4 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y +CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y +CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y +CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y +CONFIG_SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY=y +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=22 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=3 +CONFIG_SOC_SPI_MAX_CS_NUM=6 +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=72 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_SPI_SUPPORT_DDRCLK=y +CONFIG_SOC_SPI_SLAVE_SUPPORT_SEG_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CD_SIG=y +CONFIG_SOC_SPI_SUPPORT_CONTINUOUS_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2=y +CONFIG_SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT=y +CONFIG_SOC_MEMSPI_IS_INDEPENDENT=y +CONFIG_SOC_SPI_SUPPORT_OCT=y +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_SYSTIMER_COUNTER_NUM=y +CONFIG_SOC_SYSTIMER_ALARM_NUM=3 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_HI=32 +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TOUCH_VERSION_2=y +CONFIG_SOC_TOUCH_SENSOR_NUM=15 +CONFIG_SOC_TOUCH_PROXIMITY_CHANNEL_NUM=3 +CONFIG_SOC_TOUCH_PAD_THRESHOLD_MAX=0x1FFFFF +CONFIG_SOC_TOUCH_PAD_MEASURE_WAIT_MAX=0xFF +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_BRP_MAX=32768 +CONFIG_SOC_TWAI_SUPPORTS_RX_STATUS=y +CONFIG_SOC_UART_NUM=2 +CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPIRAM_XIP_SUPPORTED=y +CONFIG_SOC_USB_PERIPH_NUM=y +CONFIG_SOC_SHA_DMA_MAX_BUFFER_SIZE=3968 +CONFIG_SOC_SHA_SUPPORT_DMA=y +CONFIG_SOC_SHA_SUPPORT_RESUME=y +CONFIG_SOC_SHA_CRYPTO_DMA=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA224=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_SHA_SUPPORT_SHA512_224=y +CONFIG_SOC_SHA_SUPPORT_SHA512_256=y +CONFIG_SOC_SHA_SUPPORT_SHA512_T=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_DMA=y +CONFIG_SOC_AES_SUPPORT_GCM=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_DCACHE=y +CONFIG_SOC_EFUSE_HARD_DIS_JTAG=y +CONFIG_SOC_EFUSE_SOFT_DIS_JTAG=y +CONFIG_SOC_EFUSE_DIS_BOOT_REMAP=y +CONFIG_SOC_EFUSE_DIS_LEGACY_SPI_BOOT=y +CONFIG_SOC_EFUSE_DIS_ICACHE=y +CONFIG_SOC_SECURE_BOOT_V2_RSA=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=3 +CONFIG_SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=64 +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_256=y +CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 +CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE=4 +CONFIG_SOC_AES_CRYPTO_DMA=y +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH=12 +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_APLL_MULTIPLIER_OUT_MIN_HZ=350000000 +CONFIG_SOC_APLL_MULTIPLIER_OUT_MAX_HZ=500000000 +CONFIG_SOC_APLL_MIN_HZ=5303031 +CONFIG_SOC_APLL_MAX_HZ=125000000 +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_COEX_HW_PTI=y +CONFIG_SOC_EXTERNAL_COEX_LEADER_TX_LINE=y +CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC=y +CONFIG_SOC_WIFI_HW_TSF=y +CONFIG_SOC_WIFI_FTM_SUPPORT=y +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32s2" +CONFIG_IDF_TARGET_ESP32S2=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0002 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# end of Build type + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=0 +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +# CONFIG_BOOTLOADER_WDT_ENABLE is not set +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y +CONFIG_SECURE_BOOT_V2_PREFERRED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +CONFIG_SECURE_ROM_DL_MODE_ENABLED=y +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_REGI2C_BUG=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG=y + +# +# Boot ROM Behavior +# +CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y +# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set +# end of Boot ROM Behavior + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +# CONFIG_ESPTOOLPY_BEFORE_RESET is not set +CONFIG_ESPTOOLPY_BEFORE_NORESET=y +CONFIG_ESPTOOLPY_BEFORE="no_reset" +# CONFIG_ESPTOOLPY_AFTER_RESET is not set +CONFIG_ESPTOOLPY_AFTER_NORESET=y +CONFIG_ESPTOOLPY_AFTER="no_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +CONFIG_COMPILER_OPTIMIZATION_PERF=y +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Driver Configurations +# + +# +# Legacy ADC Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Configuration + +# +# SPI Configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI Configuration + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Temperature sensor Configuration +# +# CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set +# end of Temperature sensor Configuration + +# +# UART Configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART Configuration + +# +# GPIO Configuration +# +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of GPIO Configuration + +# +# Sigma Delta Modulator Configuration +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of Sigma Delta Modulator Configuration + +# +# GPTimer Configuration +# +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of GPTimer Configuration + +# +# PCNT Configuration +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of PCNT Configuration + +# +# RMT Configuration +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of RMT Configuration + +# +# I2S Configuration +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of I2S Configuration + +# +# DAC Configuration +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +# end of DAC Configuration +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# Ethernet +# +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +# CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32S2_REV_MIN_0=y +# CONFIG_ESP32S2_REV_MIN_1 is not set +CONFIG_ESP32S2_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32-S2 Revision (Rev v1.99) +# +CONFIG_ESP32S2_REV_MAX_FULL=199 +CONFIG_ESP_REV_MAX_FULL=199 +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO=y +# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set +# CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=576 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +CONFIG_XTAL_FREQ_40=y +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=15 +CONFIG_ESP_PHY_MAX_TX_POWER=15 +CONFIG_ESP_PHY_REDUCE_TX_POWER=y +# CONFIG_ESP_PHY_ENABLE_USB is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP PSRAM +# +CONFIG_SPIRAM=y + +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_CLK_IO=30 +CONFIG_SPIRAM_CS_IO=26 +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM_SPEED=80 +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +# CONFIG_SPIRAM_USE_MEMMAP is not set +CONFIG_SPIRAM_USE_CAPS_ALLOC=y +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 + +# +# Cache config +# +CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set +# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y +CONFIG_ESP32S2_DATA_CACHE_8KB=y +# CONFIG_ESP32S2_DATA_CACHE_16KB is not set +# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set +# end of Cache config + +# +# Memory +# +# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32S2_TRAX is not set +CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +# CONFIG_ESP_SYSTEM_MEMPROT_FEATURE is not set +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_CDC is not set +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_TASK_WDT_EN=y +# CONFIG_ESP_TASK_WDT_INIT is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=7 +# end of Brownout Detector + +# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 +# end of IPC (Inter-Processor Call) + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY=0x1 +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_TX_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +# CONFIG_ESP_WIFI_SOFTAP_SUPPORT is not set +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_SUITE_B_192 is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +CONFIG_FREERTOS_UNICORE=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# end of Port + +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +CONFIG_IEEE802154_CCA_THRESHOLD=-60 +CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 + +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=0 +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +# CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES is not set +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_TIMERS_ONDEMAND is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +# CONFIG_LWIP_SO_REUSE is not set +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# CONFIG_LWIP_IP4_FRAG is not set +# CONFIG_LWIP_IP4_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +# CONFIG_LWIP_DHCPS is not set +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# CONFIG_LWIP_NETIF_LOOPBACK is not set + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +# CONFIG_LWIP_WND_SCALE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +# CONFIG_LWIP_ESP_LWIP_ASSERT is not set + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +# CONFIG_MBEDTLS_HAVE_TIME is not set +# CONFIG_MBEDTLS_ECDSA_DETERMINISTIC is not set +# CONFIG_MBEDTLS_SHA512_C is not set +# CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT is not set +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +CONFIG_MBEDTLS_TLS_DISABLED=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_PROTOCOL_5 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# Thread Operational Dataset +# +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" +CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 +CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" +CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" +# end of Thread Operational Dataset +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=1024 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y +# CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_GD_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +# CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE is not set +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +# CONFIG_WS_TRANSPORT is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +CONFIG_ULP_COPROC_ENABLED=y +# CONFIG_ULP_COPROC_TYPE_FSM is not set +CONFIG_ULP_COPROC_TYPE_RISCV=y +CONFIG_ULP_COPROC_RESERVE_MEM=8168 + +# +# ULP RISC-V Settings +# +CONFIG_ULP_RISCV_UART_BAUDRATE=9600 +CONFIG_ULP_RISCV_I2C_RW_TIMEOUT=500 +# end of ULP RISC-V Settings +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +# CONFIG_UNITY_ENABLE_FLOAT is not set +# CONFIG_UNITY_ENABLE_DOUBLE is not set +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +# CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER is not set +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# USB-OTG +# +CONFIG_USB_OTG_SUPPORTED=y +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 +CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y +# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set +# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# +# Root Hub configuration +# +CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 +CONFIG_USB_HOST_RESET_HOLD_MS=30 +CONFIG_USB_HOST_RESET_RECOVERY_MS=30 +CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 +# end of Root Hub configuration +# end of USB-OTG + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION=y +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32S2_NO_BLOBS is not set +CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=0 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_EXTERNAL_COEX_ENABLE is not set +# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_OTA_ALLOW_HTTP is not set +CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=15 +CONFIG_ESP32_PHY_MAX_TX_POWER=15 +CONFIG_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ=240 +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y +# CONFIG_ESP32S2_MEMPROT_FEATURE is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=8192 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +# CONFIG_TASK_WDT is not set +# CONFIG_ESP_TASK_WDT is not set +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S2_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32S2_BROWNOUT_DET=y +CONFIG_ESP32S2_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S2_BROWNOUT_DET_LVL=7 +CONFIG_IPC_TASK_STACK_SIZE=1536 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_ESP_GRATUITOUS_ARP is not set +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_SYSTIMER=y +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RISCV=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=8168 +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/esp32s2/videoending/.gitignore b/esp32s2/videoending/.gitignore new file mode 100644 index 0000000..af96791 --- /dev/null +++ b/esp32s2/videoending/.gitignore @@ -0,0 +1,2 @@ +.vscode +build diff --git a/esp32s2/videoending/CMakeLists.txt b/esp32s2/videoending/CMakeLists.txt new file mode 100644 index 0000000..b0a72d1 --- /dev/null +++ b/esp32s2/videoending/CMakeLists.txt @@ -0,0 +1,23 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + + +add_custom_target(stub_bootload + # If the swadge is running reboot it into the bootloader. + COMMAND make -C ../tools/reboot_into_bootloader reboot + COMMAND sleep 0.5 +) +#add_dependencies(flash before_flash) +add_custom_target(stub_run + #Sometimes the swadge needs a kick to get rebooted + COMMAND sleep 0.5 + COMMAND esptool.py --before no_reset --after no_reset load_ram ../tools/bootload_reboot_stub/bootload_reboot_stub.bin +) + + +project(usb_sandbox) + + diff --git a/esp32s2/videoending/main/CMakeLists.txt b/esp32s2/videoending/main/CMakeLists.txt new file mode 100644 index 0000000..9387585 --- /dev/null +++ b/esp32s2/videoending/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "main.c" "app.c" + INCLUDE_DIRS "" ) + + diff --git a/esp32s2/videoending/main/app.c b/esp32s2/videoending/main/app.c new file mode 100644 index 0000000..e8d3fef --- /dev/null +++ b/esp32s2/videoending/main/app.c @@ -0,0 +1,357 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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 "esp_system.h" +#include "hal/gpio_types.h" +#include "esp_log.h" +#include "soc/efuse_reg.h" +#include "soc/soc.h" +#include "soc/system_reg.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "soc/gpio_sig_map.h" + + +#include "soc/io_mux_reg.h" +#include "soc/dedic_gpio_reg.h" + +#include "image.h" + + +// Funtenna will output on GPIO1 and 14. Otherwise it will be 17 and 18 +//#define FUNTENNA + +int global_i = 100; + + +static inline uint32_t getCycleCount() +{ + uint32_t ccount; + asm volatile("rsr %0,ccount":"=a" (ccount)); + return ccount; +} + + +#define IO_MUX_REG(x) XIO_MUX_REG(x) +#define XIO_MUX_REG(x) IO_MUX_GPIO##x##_REG + +#define GPIO_NUM(x) XGPIO_NUM(x) +#define XGPIO_NUM(x) GPIO_NUM_##x + + +#ifdef FUNTENNA + +#define RF1_PIN 1 +#define RF2_PIN 14 +#else +#define RF1_PIN 17 +#define RF2_PIN 18 +#endif + + + +#include "hal/gpio_types.h" +#include "driver/gpio.h" +#include "rom/gpio.h" +#include "soc/i2s_reg.h" +#include "soc/periph_defs.h" +#include "rom/lldesc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc.h" +#include "soc/regi2c_apll.h" +//#include "components/hal/esp32s2/include/hal/regi2c_ctrl_ll.h +#include "hal/regi2c_ctrl_ll.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/regi2c_ctrl.h" +#include "hal/clk_tree_ll.h" + +#include "siggen.h" + + + + +#define I2C_RTC_WIFI_CLK_EN (SYSCON_WIFI_CLK_EN_REG) + +#define I2C_RTC_CLK_GATE_EN (BIT(18)) +#define I2C_RTC_CLK_GATE_EN_M (BIT(18)) +#define I2C_RTC_CLK_GATE_EN_V 0x1 +#define I2C_RTC_CLK_GATE_EN_S 18 + +#define I2C_RTC_CONFIG0 0x6000e048 + +#define I2C_RTC_MAGIC_CTRL 0x00001FFF +#define I2C_RTC_MAGIC_CTRL_M ((I2C_RTC_MAGIC_CTRL_V)<<(I2C_RTC_MAGIC_CTRL_S)) +#define I2C_RTC_MAGIC_CTRL_V 0x1FFF +#define I2C_RTC_MAGIC_CTRL_S 4 + +#define I2C_RTC_CONFIG1 0x6000e044 + +#define I2C_RTC_BOD_MASK (BIT(22)) +#define I2C_RTC_BOD_MASK_M (BIT(22)) +#define I2C_RTC_BOD_MASK_V 0x1 +#define I2C_RTC_BOD_MASK_S 22 + +#define I2C_RTC_SAR_MASK (BIT(18)) +#define I2C_RTC_SAR_MASK_M (BIT(18)) +#define I2C_RTC_SAR_MASK_V 0x1 +#define I2C_RTC_SAR_MASK_S 18 + +#define I2C_RTC_BBPLL_MASK (BIT(17)) +#define I2C_RTC_BBPLL_MASK_M (BIT(17)) +#define I2C_RTC_BBPLL_MASK_V 0x1 +#define I2C_RTC_BBPLL_MASK_S 17 + +#define I2C_RTC_APLL_MASK (BIT(14)) +#define I2C_RTC_APLL_MASK_M (BIT(14)) +#define I2C_RTC_APLL_MASK_V 0x1 +#define I2C_RTC_APLL_MASK_S 14 + +#define I2C_RTC_ALL_MASK 0x00007FFF +#define I2C_RTC_ALL_MASK_M ((I2C_RTC_ALL_MASK_V)<<(I2C_RTC_ALL_MASK_S)) +#define I2C_RTC_ALL_MASK_V 0x7FFF +#define I2C_RTC_ALL_MASK_S 8 + +#define I2C_RTC_CONFIG2 0x6000e000 + +#define I2C_RTC_BUSY (BIT(25)) +#define I2C_RTC_BUSY_M (BIT(25)) +#define I2C_RTC_BUSY_V 0x1 +#define I2C_RTC_BUSY_S 25 + +#define I2C_RTC_WR_CNTL (BIT(24)) +#define I2C_RTC_WR_CNTL_M (BIT(24)) +#define I2C_RTC_WR_CNTL_V 0x1 +#define I2C_RTC_WR_CNTL_S 24 + +#define I2C_RTC_DATA 0x000000FF +#define I2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S)) +#define I2C_RTC_DATA_V 0xFF +#define I2C_RTC_DATA_S 16 + +#define I2C_RTC_ADDR 0x000000FF +#define I2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S)) +#define I2C_RTC_ADDR_V 0xFF +#define I2C_RTC_ADDR_S 8 + +#define I2C_RTC_SLAVE_ID 0x000000FF +#define I2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S)) +#define I2C_RTC_SLAVE_ID_V 0xFF +#define I2C_RTC_SLAVE_ID_S 0 + +#define I2C_RTC_MAGIC_DEFAULT (0x1c40) + +#define I2C_BOD 0x61 +#define I2C_BBPLL 0x66 +#define I2C_SAR_ADC 0X69 +#define I2C_APLL 0X6D + + +int lastend = 0; + +// Configures APLL = 480 / 4 = 120 +// 40 * (SDM2 + SDM1/(2^8) + SDM0/(2^16) + 4) / ( 2 * (ODIV+2) ); +// Datasheet recommends that numerator does not exceed 500MHz. +void IRAM_ATTR local_rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div) +{ + REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1); + REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0); + + if (enable) { + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM2, sdm2); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM0, sdm0); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_DSDM1, sdm1); + REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_1); + REGI2C_WRITE(I2C_APLL, I2C_APLL_SDM_STOP, CLK_LL_APLL_SDM_STOP_VAL_2_REV1); + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div ); + } + + + // Settings determined experimentally. + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_TSCHGP, 0 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_EN_FAST_CAL, 1 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DHREF_SEL, 0 ); // 0..3 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DLREF_SEL, 0 ); // 0..3 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_SDM_DITHER, 1 ); // 0 or 1 + REGI2C_WRITE_MASK(I2C_APLL, I2C_APLL_OC_DVDD, 25 ); // 0 .. 31 + +} + + +void IRAM_ATTR regi2c_write_reg_raw_local(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +{ + uint32_t temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S) + | ((reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S) + | ((0x1 & I2C_RTC_WR_CNTL_V) << I2C_RTC_WR_CNTL_S) + | (((uint32_t)data & I2C_RTC_DATA_V) << I2C_RTC_DATA_S); + while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY)); + REG_WRITE(I2C_RTC_CONFIG2, temp); +} + + +void apll_quick_update( uint32_t sdm ) +{ + uint8_t sdm2 = sdm>>16; + uint8_t sdm1 = (sdm>>8)&0xff; + uint8_t sdm0 = (sdm>>0)&0xff; + static int last_sdm_0 = -1; + static int last_sdm_1 = -1; + static int last_sdm_2 = -1; + + if( sdm2 != last_sdm_2 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM2, sdm2); + if( sdm0 != last_sdm_0 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM0, sdm0); + if( sdm1 != last_sdm_1 ) + regi2c_write_reg_raw_local(I2C_APLL, I2C_APLL_HOSTID, I2C_APLL_DSDM1, sdm1); + + last_sdm_2 = sdm2; + last_sdm_1 = sdm1; + last_sdm_0 = sdm0; +} + + + +void sandbox_main() +{ + printf( "sandbox_main()\n" ); + + + + DPORT_SET_PERI_REG_MASK( DPORT_CPU_PERI_CLK_EN_REG, DPORT_CLK_EN_DEDICATED_GPIO ); + DPORT_CLEAR_PERI_REG_MASK( DPORT_CPU_PERI_RST_EN_REG, DPORT_RST_EN_DEDICATED_GPIO); + + // Setup GPIO39 to be the PRO ALONE output (For LEDs) + REG_WRITE( GPIO_OUT1_W1TC_REG, 1<<(39-32) ); + REG_WRITE( GPIO_ENABLE1_W1TS_REG, 1<<(39-32) ); + REG_WRITE( IO_MUX_GPIO39_REG, 2< + +#define IMAGEOH 412 +#define IMAGEOPL 32 +uint16_t imageout[IMAGEOH*IMAGEOPL] = { +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, +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, +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, +238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +235, 236, 237, 238, 256, 257, 258, 259, 260, 261, 273, 274, 275, 276, 277, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +232, 233, 234, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 278, 279, 280, 281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +230, 231, 232, 282, 283, 284, 285, 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, +228, 229, 285, 286, 287, 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, +226, 227, 228, 287, 288, 289, 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, +222, 223, 224, 225, 226, 289, 290, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +220, 221, 222, 291, 292, 293, 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, +218, 219, 294, 295, 296, 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, +216, 217, 296, 297, 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, +213, 214, 215, 298, 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, +211, 212, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 299, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +209, 210, 228, 229, 230, 231, 246, 247, 248, 249, 301, 302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +207, 208, 223, 224, 225, 226, 227, 250, 251, 252, 253, 254, 302, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +204, 205, 206, 207, 220, 221, 222, 223, 254, 255, 256, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +202, 203, 204, 217, 218, 219, 256, 257, 258, 259, 294, 295, 305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +201, 202, 213, 214, 215, 216, 259, 260, 261, 295, 296, 297, 306, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +199, 200, 210, 211, 212, 213, 261, 262, 297, 307, 308, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +198, 199, 208, 209, 210, 262, 263, 264, 265, 297, 298, 309, 310, 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +197, 198, 266, 267, 268, 298, 311, 312, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +196, 197, 269, 270, 271, 298, 313, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +196, 271, 272, 273, 299, 314, 315, 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, +195, 196, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 274, 275, 299, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +195, 231, 232, 233, 234, 235, 246, 247, 248, 275, 276, 277, 278, 299, 300, 317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +194, 229, 230, 231, 249, 250, 251, 278, 279, 280, 281, 300, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +194, 226, 227, 228, 229, 251, 252, 253, 281, 282, 283, 300, 318, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +193, 224, 225, 226, 253, 254, 255, 284, 301, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +192, 193, 221, 222, 223, 255, 256, 257, 258, 285, 286, 301, 302, 320, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +192, 218, 219, 220, 258, 259, 287, 288, 302, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +191, 192, 213, 214, 215, 216, 217, 259, 260, 261, 262, 288, 289, 302, 321, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +189, 190, 210, 211, 212, 213, 262, 263, 290, 291, 302, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +188, 189, 207, 208, 209, 264, 292, 293, 302, 303, 322, 323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +187, 188, 204, 205, 206, 265, 294, 295, 303, 323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +186, 187, 203, 204, 266, 296, 303, 323, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +185, 186, 200, 201, 202, 267, 304, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +183, 184, 199, 267, 304, 324, 325, 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, +182, 183, 196, 197, 198, 268, 304, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +180, 181, 182, 193, 194, 195, 269, 304, 305, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +180, 270, 305, 325, 326, 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, +179, 271, 305, 326, 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, +178, 179, 227, 228, 229, 230, 272, 305, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +178, 222, 223, 224, 225, 226, 230, 231, 232, 233, 272, 273, 305, 306, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +178, 218, 219, 220, 221, 234, 235, 236, 273, 274, 306, 327, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +177, 178, 215, 216, 217, 218, 236, 237, 238, 239, 274, 275, 306, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +177, 213, 214, 215, 240, 241, 275, 306, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +177, 209, 210, 211, 212, 213, 241, 242, 243, 276, 307, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +176, 177, 207, 208, 209, 243, 244, 276, 277, 307, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +176, 205, 206, 207, 245, 246, 277, 307, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +176, 203, 204, 247, 277, 278, 307, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +176, 202, 203, 248, 249, 278, 307, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +175, 176, 200, 201, 249, 250, 278, 279, 308, 331, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +175, 199, 200, 215, 216, 217, 218, 219, 220, 221, 222, 223, 250, 251, 279, 280, 308, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +175, 195, 196, 197, 198, 199, 212, 213, 214, 215, 224, 225, 226, 252, 253, 280, 308, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 175, 193, 194, 195, 211, 212, 226, 227, 228, 229, 254, 280, 281, 309, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 191, 192, 193, 209, 210, 229, 230, 231, 254, 255, 281, 309, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 188, 189, 190, 207, 208, 209, 231, 232, 233, 256, 282, 309, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 181, 182, 185, 186, 187, 205, 206, 207, 233, 234, 256, 257, 282, 309, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 182, 183, 184, 204, 205, 235, 257, 258, 283, 309, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 203, 204, 235, 236, 258, 259, 284, 336, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 202, 203, 236, 259, 284, 285, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 201, 236, 259, 285, 286, 311, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 199, 200, 237, 260, 286, 309, 310, 311, 312, 337, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 199, 237, 260, 286, 287, 308, 309, 312, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 174, 197, 198, 238, 261, 287, 307, 308, 312, 338, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 197, 238, 262, 306, 312, 339, 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, +173, 196, 238, 262, 306, 312, 339, 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, +173, 195, 239, 262, 263, 306, 312, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 194, 195, 239, 263, 305, 306, 312, 313, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 193, 194, 240, 303, 304, 305, 313, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 191, 192, 193, 299, 300, 301, 302, 303, 313, 314, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 189, 190, 191, 296, 297, 298, 314, 339, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 180, 181, 182, 183, 184, 185, 186, 187, 188, 219, 220, 221, 222, 223, 295, 296, 315, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 218, 219, 224, 225, 294, 295, 316, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 217, 225, 292, 293, 317, 340, 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, +172, 216, 226, 291, 292, 317, 318, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 214, 215, 226, 289, 290, 318, 319, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 213, 214, 226, 288, 289, 319, 340, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 212, 213, 226, 227, 285, 286, 287, 288, 319, 320, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 212, 227, 228, 284, 285, 320, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 211, 228, 229, 230, 281, 282, 283, 320, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 210, 230, 231, 232, 280, 281, 320, 321, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 210, 232, 233, 234, 278, 279, 321, 341, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 209, 235, 236, 277, 278, 321, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 208, 209, 236, 237, 238, 275, 276, 321, 322, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 207, 238, 239, 240, 241, 244, 245, 246, 247, 248, 249, 250, 251, 275, 322, 323, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 207, 241, 242, 243, 251, 252, 273, 274, 323, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 206, 207, 252, 253, 273, 324, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 205, 253, 254, 272, 273, 325, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 205, 254, 255, 272, 326, 327, 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 204, 255, 271, 327, 342, 343, 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, +171, 204, 255, 271, 294, 295, 296, 297, 328, 341, 342, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 203, 255, 256, 257, 270, 289, 290, 291, 292, 293, 294, 329, 341, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 203, 257, 269, 287, 288, 329, 340, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 202, 257, 258, 267, 268, 286, 287, 330, 340, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 201, 202, 259, 260, 266, 267, 284, 285, 330, 340, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 201, 260, 261, 262, 263, 264, 265, 266, 282, 283, 302, 303, 304, 305, 330, 340, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 200, 281, 299, 300, 301, 302, 331, 340, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 200, 279, 280, 295, 296, 297, 298, 331, 340, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 199, 200, 277, 278, 279, 292, 293, 294, 331, 340, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 199, 276, 277, 291, 331, 340, 341, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 172, 199, 274, 275, 331, 341, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 199, 273, 274, 331, 340, 344, 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, +172, 199, 272, 331, 340, 344, 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, +172, 199, 270, 271, 331, 340, 344, 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, +172, 199, 238, 239, 240, 241, 242, 255, 256, 257, 258, 259, 260, 261, 267, 268, 269, 270, 331, 332, 339, 340, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, +172, 199, 237, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 261, 262, 263, 264, 265, 266, 267, 295, 296, 297, 298, 332, 339, 343, 0, +172, 199, 290, 291, 292, 293, 294, 295, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 199, 285, 286, 287, 288, 289, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 199, 282, 283, 284, 285, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 199, 200, 279, 280, 281, 282, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 200, 276, 277, 278, 279, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 200, 274, 275, 276, 297, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 200, 271, 272, 273, 274, 295, 296, 297, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 200, 241, 242, 243, 244, 254, 255, 256, 257, 258, 259, 260, 261, 262, 270, 271, 294, 295, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +200, 235, 236, 238, 239, 240, 245, 246, 247, 252, 253, 263, 264, 265, 266, 267, 268, 269, 270, 292, 293, 332, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, +172, 173, 174, 200, 201, 236, 237, 248, 249, 250, 251, 267, 268, 289, 290, 291, 332, 338, 339, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 175, 201, 285, 286, 287, 288, 289, 332, 338, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 172, 176, 201, 280, 281, 282, 283, 284, 285, 298, 299, 332, 333, 338, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 176, 177, 201, 277, 278, 279, 296, 297, 333, 337, 338, 342, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 177, 201, 275, 276, 295, 333, 337, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 178, 201, 259, 260, 261, 262, 274, 275, 293, 294, 333, 334, 337, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 178, 201, 263, 264, 272, 273, 291, 292, 334, 335, 336, 337, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 179, 201, 264, 265, 266, 267, 268, 269, 270, 271, 272, 290, 291, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 179, 180, 201, 289, 290, 343, 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, +171, 180, 181, 201, 242, 243, 244, 245, 246, 288, 289, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 181, 201, 241, 242, 246, 247, 248, 249, 250, 287, 288, 309, 310, 311, 312, 313, 314, 315, 342, 343, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +171, 181, 201, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 286, 304, 305, 306, 307, 308, 309, 316, 317, 318, 342, 0, 0, 0, 0, 0, 0, 0, 0, +171, 172, 181, 182, 201, 284, 285, 300, 301, 302, 303, 304, 318, 319, 320, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 182, 201, 283, 284, 298, 299, 300, 320, 321, 322, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 182, 183, 201, 295, 296, 297, 322, 323, 324, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +172, 173, 183, 200, 201, 293, 294, 295, 316, 317, 318, 319, 320, 321, 324, 325, 341, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 183, 200, 292, 293, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 321, 322, 323, 324, 325, 341, 0, 0, 0, 0, 0, 0, 0, 0, +173, 184, 200, 291, 300, 301, 302, 303, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 184, 185, 199, 200, 290, 291, 297, 298, 299, 300, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +173, 185, 199, 289, 290, 295, 296, 297, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 185, 198, 199, 289, 294, 295, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 185, 198, 288, 292, 293, 294, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +174, 175, 185, 186, 197, 198, 238, 239, 240, 241, 242, 243, 244, 245, 286, 287, 291, 292, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +175, 186, 187, 197, 232, 233, 234, 235, 236, 237, 238, 245, 246, 247, 248, 285, 290, 291, 340, 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +175, 187, 188, 197, 226, 227, 228, 229, 230, 231, 232, 249, 250, 284, 288, 289, 290, 305, 306, 307, 308, 309, 310, 311, 340, 0, 0, 0, 0, 0, 0, 0, +176, 177, 188, 189, 197, 220, 221, 222, 223, 224, 225, 237, 238, 239, 240, 241, 242, 251, 252, 284, 285, 286, 287, 288, 303, 304, 312, 313, 339, 340, 0, 0, +177, 189, 190, 197, 217, 218, 219, 232, 233, 234, 235, 236, 243, 244, 245, 253, 254, 300, 301, 302, 303, 313, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, +177, 178, 190, 191, 196, 217, 229, 230, 231, 246, 247, 248, 255, 256, 257, 258, 297, 298, 299, 300, 302, 313, 314, 339, 0, 0, 0, 0, 0, 0, 0, 0, +178, 192, 196, 216, 225, 226, 227, 228, 229, 248, 249, 250, 251, 252, 253, 259, 260, 297, 300, 301, 302, 303, 314, 339, 0, 0, 0, 0, 0, 0, 0, 0, +179, 192, 196, 216, 222, 223, 224, 225, 253, 254, 255, 256, 259, 260, 295, 296, 299, 300, 303, 304, 314, 338, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, +179, 180, 193, 195, 215, 216, 220, 221, 222, 256, 257, 258, 259, 295, 297, 298, 304, 314, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +180, 193, 194, 195, 215, 216, 218, 219, 294, 297, 298, 303, 304, 311, 312, 313, 314, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +180, 194, 216, 217, 218, 293, 298, 299, 300, 301, 303, 309, 310, 311, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +181, 292, 301, 302, 303, 306, 307, 308, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +181, 292, 304, 305, 306, 337, 338, 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, +181, 182, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 292, 293, 302, 303, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +182, 235, 236, 239, 240, 241, 242, 243, 244, 247, 248, 249, 250, 293, 294, 295, 296, 297, 298, 299, 300, 301, 336, 337, 0, 0, 0, 0, 0, 0, 0, 0, +182, 183, 234, 238, 239, 244, 245, 250, 251, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +183, 233, 237, 238, 245, 251, 252, 282, 283, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +184, 232, 233, 237, 244, 245, 253, 282, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +184, 230, 231, 232, 237, 244, 253, 254, 282, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +184, 185, 228, 229, 230, 237, 238, 239, 240, 241, 242, 243, 254, 281, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +185, 226, 227, 228, 254, 281, 336, 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, +185, 227, 228, 229, 230, 253, 254, 281, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +185, 231, 232, 252, 253, 281, 336, 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, +186, 231, 232, 233, 234, 235, 236, 237, 238, 239, 246, 247, 248, 249, 250, 251, 252, 281, 336, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +186, 240, 241, 242, 243, 244, 245, 281, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +186, 187, 281, 337, 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, +187, 281, 337, 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, +187, 281, 336, 337, 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, +187, 281, 336, 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, +187, 188, 281, 336, 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, +188, 281, 336, 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, +189, 281, 336, 337, 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, +189, 190, 281, 337, 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, +190, 191, 281, 337, 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, +104, 105, 106, 107, 108, 109, 110, 111, 112, 191, 281, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +102, 103, 104, 112, 113, 192, 281, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +101, 102, 113, 114, 192, 193, 281, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +100, 101, 114, 115, 193, 194, 281, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +100, 115, 116, 173, 174, 175, 176, 177, 194, 195, 196, 197, 281, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +100, 116, 117, 166, 167, 168, 169, 170, 171, 172, 177, 178, 179, 180, 197, 198, 199, 281, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +99, 100, 117, 118, 161, 162, 163, 164, 165, 166, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 199, 200, 281, 296, 297, 337, 0, 0, 0, 0, 0, +99, 118, 119, 159, 160, 161, 191, 192, 193, 194, 195, 200, 281, 298, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +98, 99, 119, 120, 156, 157, 158, 196, 197, 200, 202, 203, 204, 205, 206, 207, 281, 299, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +98, 120, 121, 153, 154, 155, 156, 198, 199, 200, 201, 208, 209, 210, 211, 281, 282, 300, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +98, 121, 122, 150, 151, 152, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 282, 301, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +98, 99, 122, 123, 147, 148, 149, 150, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 260, 282, 301, 302, 337, 0, 0, +99, 123, 145, 146, 238, 239, 240, 241, 258, 259, 282, 302, 303, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +99, 124, 142, 143, 144, 242, 243, 257, 258, 282, 283, 298, 303, 304, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +99, 124, 125, 138, 139, 140, 141, 243, 244, 256, 283, 297, 298, 304, 305, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +99, 125, 136, 137, 138, 245, 255, 283, 296, 297, 305, 306, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +99, 125, 126, 132, 133, 134, 135, 246, 254, 255, 283, 296, 306, 307, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +99, 126, 127, 128, 129, 130, 131, 132, 247, 254, 257, 284, 296, 307, 308, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +100, 126, 247, 248, 253, 257, 284, 295, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +100, 126, 248, 253, 258, 284, 294, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +100, 101, 126, 127, 248, 252, 259, 284, 293, 313, 319, 320, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +101, 127, 248, 251, 260, 284, 285, 292, 313, 314, 321, 322, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +101, 126, 127, 128, 248, 251, 261, 285, 291, 314, 315, 323, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +101, 102, 124, 125, 128, 249, 250, 261, 262, 290, 315, 316, 323, 324, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +102, 123, 129, 249, 250, 262, 263, 289, 315, 316, 324, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +102, 122, 129, 130, 249, 263, 264, 288, 314, 315, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +102, 121, 249, 265, 266, 287, 310, 311, 312, 313, 314, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +103, 120, 121, 249, 250, 266, 267, 285, 286, 307, 308, 309, 310, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +103, 120, 250, 268, 269, 284, 285, 306, 307, 322, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +103, 104, 119, 250, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 282, 283, 284, 305, 306, 321, 322, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 119, 250, 278, 279, 280, 281, 282, 304, 321, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 119, 250, 302, 303, 320, 321, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +105, 118, 250, 300, 301, 320, 331, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +105, 106, 118, 250, 298, 299, 300, 319, 330, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +106, 118, 249, 250, 296, 297, 298, 319, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +106, 117, 249, 295, 296, 318, 329, 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, +106, 117, 249, 293, 294, 295, 318, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +106, 117, 249, 291, 292, 293, 317, 327, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +106, 117, 249, 289, 290, 291, 317, 326, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +106, 117, 248, 249, 285, 286, 287, 288, 289, 316, 317, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +106, 117, 248, 249, 250, 251, 258, 259, 278, 279, 280, 281, 282, 283, 284, 285, 316, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +106, 117, 248, 251, 252, 253, 254, 255, 256, 257, 258, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 316, 324, +106, 117, 248, 316, 323, 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, +106, 117, 247, 248, 322, 323, 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, +105, 118, 247, 322, 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, +105, 118, 247, 321, 322, 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, +105, 118, 246, 321, 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, +105, 118, 246, 320, 321, 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, +105, 118, 119, 245, 320, 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, +104, 119, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 244, 245, 319, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 119, 139, 140, 141, 142, 143, 155, 156, 244, 319, 323, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 119, 120, 135, 136, 137, 138, 157, 244, 318, 323, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 157, 158, 243, 318, 321, 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 158, 159, 243, 317, 318, 321, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 159, 243, 317, 321, 325, 326, 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, +104, 160, 161, 243, 316, 317, 321, 326, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 161, 242, 316, 321, 327, 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, +104, 162, 242, 315, 321, 327, 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, +103, 104, 162, 163, 242, 315, 321, 327, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +103, 163, 241, 314, 321, 328, 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, +102, 103, 163, 164, 241, 313, 314, 321, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +101, 164, 240, 313, 321, 329, 330, 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, +100, 164, 240, 313, 321, 330, 331, 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, +99, 164, 239, 240, 312, 313, 321, 331, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +98, 99, 163, 164, 239, 312, 321, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +98, 163, 239, 240, 241, 311, 312, 321, 332, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +97, 162, 163, 239, 240, 241, 242, 311, 321, 333, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +96, 161, 162, 238, 239, 242, 243, 244, 310, 321, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +96, 159, 160, 161, 237, 238, 244, 245, 309, 321, 334, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +96, 155, 156, 157, 158, 237, 245, 246, 308, 309, 321, 335, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +95, 96, 147, 148, 149, 150, 151, 152, 153, 154, 155, 236, 246, 307, 308, 321, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +95, 140, 141, 142, 143, 144, 145, 146, 235, 236, 246, 247, 306, 307, 321, 336, 337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +95, 138, 139, 140, 183, 184, 185, 186, 187, 188, 234, 235, 237, 238, 247, 248, 306, 321, 337, 338, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +94, 138, 174, 175, 176, 177, 178, 179, 180, 181, 182, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 234, 236, 239, 240, 248, 305, 321, 339, 0, 0, 0, +94, 137, 138, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 198, 199, 233, 234, 236, 241, 242, 248, 249, 304, 305, 320, 321, 339, 340, 0, 0, 0, +94, 137, 155, 156, 157, 158, 159, 160, 161, 162, 163, 199, 200, 232, 237, 243, 244, 249, 250, 303, 304, 310, 311, 312, 313, 314, 315, 317, 318, 320, 340, 341, +94, 137, 138, 139, 151, 152, 153, 154, 155, 200, 201, 230, 231, 237, 244, 245, 246, 250, 251, 303, 305, 306, 307, 308, 309, 316, 317, 318, 319, 320, 342, 343, +94, 137, 138, 139, 146, 147, 148, 149, 150, 151, 201, 202, 229, 238, 246, 247, 248, 252, 253, 302, 304, 305, 320, 321, 322, 323, 343, 344, 0, 0, 0, 0, +94, 95, 136, 140, 141, 142, 143, 144, 145, 146, 202, 203, 228, 229, 239, 248, 249, 250, 251, 252, 254, 255, 256, 300, 301, 320, 323, 324, 345, 346, 347, 0, +89, 90, 91, 92, 93, 95, 135, 203, 204, 208, 226, 227, 239, 240, 252, 253, 254, 255, 256, 257, 299, 300, 324, 325, 347, 348, 0, 0, 0, 0, 0, 0, +83, 84, 85, 86, 87, 88, 95, 134, 204, 205, 207, 208, 212, 213, 214, 215, 216, 217, 226, 241, 251, 252, 257, 258, 298, 325, 349, 0, 0, 0, 0, 0, +81, 82, 95, 96, 133, 134, 205, 206, 207, 208, 209, 210, 211, 217, 218, 219, 225, 241, 242, 251, 258, 259, 260, 297, 298, 325, 349, 350, 351, 0, 0, 0, +77, 78, 79, 80, 81, 96, 131, 132, 133, 207, 208, 219, 224, 242, 243, 251, 260, 261, 262, 296, 297, 325, 351, 352, 353, 0, 0, 0, 0, 0, 0, 0, +77, 96, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 207, 219, 220, 223, 224, 243, 244, 251, 262, 263, 264, 265, 294, 295, 296, 326, 353, 354, 355, +75, 76, 77, 97, 207, 220, 221, 222, 244, 251, 265, 266, 267, 268, 269, 270, 271, 293, 294, 326, 355, 356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +70, 71, 72, 73, 74, 75, 97, 98, 207, 221, 222, 244, 245, 250, 272, 273, 274, 291, 292, 293, 326, 356, 357, 0, 0, 0, 0, 0, 0, 0, 0, 0, +68, 69, 70, 98, 207, 221, 222, 223, 245, 246, 250, 274, 275, 276, 277, 288, 289, 290, 291, 326, 357, 358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +66, 67, 98, 207, 221, 246, 250, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 326, 327, 358, 359, 0, 0, 0, 0, 0, 0, 0, 0, 0, +64, 65, 98, 206, 221, 247, 250, 283, 287, 327, 359, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +62, 63, 98, 205, 206, 221, 247, 250, 284, 288, 327, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +61, 62, 98, 204, 205, 220, 221, 248, 249, 250, 284, 288, 327, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +61, 98, 202, 203, 204, 220, 249, 284, 288, 327, 361, 362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +59, 60, 98, 200, 201, 202, 220, 249, 284, 288, 327, 362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +59, 98, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 219, 249, 250, 284, 288, 327, 362, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +58, 98, 186, 187, 188, 192, 219, 249, 250, 284, 288, 327, 363, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +57, 58, 98, 183, 184, 185, 186, 191, 192, 218, 249, 250, 284, 288, 327, 364, 365, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +57, 98, 180, 181, 182, 183, 191, 218, 249, 250, 284, 288, 326, 365, 366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +56, 57, 98, 176, 177, 178, 179, 180, 191, 217, 218, 249, 285, 288, 289, 326, 367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +56, 98, 99, 173, 174, 175, 191, 216, 217, 250, 285, 289, 326, 368, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +55, 56, 98, 170, 171, 172, 173, 178, 179, 191, 215, 216, 250, 285, 289, 326, 370, 371, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +55, 97, 98, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 179, 191, 212, 213, 214, 215, 250, 286, 289, 326, 371, 372, 373, 0, 0, 0, 0, +54, 55, 96, 98, 156, 157, 158, 159, 179, 191, 210, 211, 212, 250, 286, 289, 326, 374, 375, 376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +54, 96, 98, 131, 132, 133, 150, 151, 152, 153, 154, 155, 179, 191, 192, 208, 209, 210, 250, 286, 289, 326, 377, 378, 379, 380, 0, 0, 0, 0, 0, 0, +54, 95, 96, 98, 133, 134, 135, 136, 137, 138, 139, 140, 141, 147, 148, 149, 150, 179, 192, 207, 208, 250, 286, 289, 326, 380, 381, 382, 383, 0, 0, 0, +54, 95, 98, 142, 143, 144, 145, 146, 179, 192, 205, 206, 250, 251, 286, 287, 289, 325, 383, 384, 385, 386, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, +53, 94, 95, 98, 179, 192, 204, 205, 251, 287, 289, 325, 387, 388, 389, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +53, 93, 94, 97, 179, 192, 202, 203, 251, 287, 289, 325, 390, 391, 392, 393, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +53, 92, 93, 97, 178, 193, 200, 201, 251, 287, 288, 325, 394, 395, 396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +53, 92, 97, 178, 193, 199, 200, 251, 286, 287, 288, 324, 397, 398, 399, 400, 401, 402, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +53, 91, 92, 97, 178, 194, 197, 198, 251, 284, 285, 286, 288, 289, 298, 299, 300, 301, 324, 403, 404, 405, 406, 407, 0, 0, 0, 0, 0, 0, 0, 0, +52, 53, 91, 97, 178, 194, 197, 252, 283, 284, 289, 290, 296, 297, 298, 301, 302, 324, 407, 408, 409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +52, 91, 96, 97, 178, 195, 196, 197, 252, 282, 283, 290, 291, 292, 293, 294, 295, 296, 303, 304, 323, 324, 410, 411, 0, 0, 0, 0, 0, 0, 0, 0, +52, 91, 96, 178, 195, 252, 253, 281, 282, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 323, 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, +52, 90, 91, 95, 96, 178, 195, 253, 281, 315, 316, 317, 321, 322, 323, 413, 414, 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +52, 90, 95, 178, 195, 254, 255, 280, 317, 318, 320, 415, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +52, 90, 95, 179, 195, 255, 256, 279, 280, 318, 319, 320, 416, 417, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +52, 89, 90, 95, 179, 195, 256, 257, 277, 278, 279, 319, 320, 418, 419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +52, 89, 95, 155, 156, 157, 158, 159, 160, 161, 162, 163, 179, 195, 258, 274, 275, 276, 320, 419, 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +51, 52, 88, 94, 152, 153, 154, 163, 164, 165, 166, 167, 178, 179, 195, 259, 272, 273, 274, 320, 421, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +51, 88, 94, 167, 168, 169, 170, 171, 177, 179, 195, 260, 270, 271, 272, 320, 422, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +50, 51, 88, 94, 95, 171, 172, 176, 177, 179, 195, 260, 261, 264, 265, 269, 270, 320, 423, 424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +50, 88, 95, 172, 173, 175, 179, 195, 261, 262, 263, 264, 265, 266, 268, 269, 320, 425, 426, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +50, 88, 95, 173, 174, 175, 179, 195, 262, 263, 266, 267, 320, 427, 428, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +49, 50, 87, 95, 96, 174, 179, 195, 267, 320, 429, 430, 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +49, 87, 96, 170, 171, 172, 173, 179, 195, 267, 320, 431, 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +49, 87, 97, 168, 169, 170, 179, 195, 268, 320, 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +49, 87, 97, 168, 179, 195, 268, 319, 320, 433, 434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 49, 87, 98, 168, 179, 195, 269, 319, 434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 87, 98, 168, 180, 194, 269, 270, 319, 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 87, 98, 99, 167, 168, 180, 194, 270, 319, 436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 87, 99, 167, 180, 194, 270, 319, 436, 437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 87, 99, 167, 180, 194, 270, 319, 437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 87, 99, 167, 180, 194, 270, 319, 438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 99, 167, 180, 194, 271, 319, 439, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 99, 167, 180, 194, 272, 319, 440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 99, 167, 180, 194, 272, 273, 318, 319, 440, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 99, 100, 166, 167, 180, 194, 195, 273, 318, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 100, 165, 166, 180, 195, 274, 275, 318, 441, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 100, 165, 180, 195, 275, 276, 317, 318, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 100, 164, 180, 195, 276, 277, 317, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +48, 88, 100, 101, 163, 180, 195, 278, 317, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +47, 48, 88, 101, 162, 180, 195, 279, 317, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +47, 88, 101, 160, 161, 162, 180, 195, 279, 316, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +47, 88, 101, 160, 180, 194, 195, 280, 316, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +47, 89, 101, 102, 158, 159, 160, 180, 195, 280, 281, 316, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +46, 47, 89, 102, 155, 156, 157, 158, 180, 195, 281, 316, 442, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +46, 89, 102, 153, 154, 155, 157, 180, 195, 282, 316, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +46, 89, 102, 103, 150, 151, 152, 153, 156, 180, 195, 283, 316, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +45, 46, 89, 103, 148, 149, 150, 156, 180, 195, 283, 284, 316, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +45, 89, 103, 147, 156, 180, 194, 195, 284, 285, 316, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +45, 89, 103, 146, 155, 180, 194, 285, 286, 316, 442, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +45, 89, 90, 103, 145, 155, 180, 194, 286, 315, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 90, 104, 144, 145, 154, 155, 180, 194, 286, 315, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 90, 104, 144, 154, 180, 194, 286, 287, 315, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 90, 104, 105, 143, 153, 154, 180, 194, 287, 315, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 90, 91, 105, 143, 153, 180, 194, 287, 314, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 91, 105, 142, 152, 180, 194, 288, 314, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 92, 105, 142, 151, 152, 181, 194, 288, 314, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 92, 106, 141, 142, 151, 181, 194, 288, 289, 314, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +44, 92, 106, 107, 141, 150, 181, 194, 289, 314, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +43, 92, 93, 107, 141, 149, 150, 181, 194, 290, 314, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +43, 93, 107, 140, 141, 148, 181, 194, 290, 314, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +43, 93, 107, 139, 140, 148, 181, 194, 290, 314, 443, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +43, 93, 107, 108, 139, 146, 147, 148, 181, 194, 291, 314, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +43, 94, 108, 109, 138, 139, 145, 146, 181, 194, 291, 314, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +42, 43, 94, 109, 110, 137, 138, 144, 181, 194, 291, 292, 314, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +42, 94, 95, 110, 111, 112, 136, 143, 180, 181, 194, 292, 314, 444, 445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +41, 95, 112, 113, 135, 142, 143, 180, 194, 292, 313, 314, 445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +40, 41, 95, 96, 114, 115, 134, 135, 141, 142, 180, 194, 292, 293, 313, 445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +40, 96, 116, 133, 140, 180, 194, 195, 293, 313, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +40, 96, 97, 116, 117, 131, 132, 133, 140, 179, 180, 195, 293, 294, 313, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +39, 40, 97, 117, 131, 139, 140, 179, 195, 294, 312, 313, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +38, 39, 97, 98, 118, 129, 130, 138, 139, 179, 195, 196, 294, 295, 312, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +38, 98, 99, 118, 129, 138, 179, 196, 295, 296, 312, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +37, 99, 118, 128, 137, 138, 179, 196, 296, 312, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +36, 37, 99, 118, 127, 137, 179, 196, 297, 311, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +35, 99, 100, 118, 126, 136, 137, 178, 196, 297, 311, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +34, 35, 100, 118, 126, 136, 178, 197, 298, 311, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +33, 34, 100, 118, 125, 136, 178, 197, 298, 299, 311, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +33, 100, 101, 118, 124, 125, 135, 177, 178, 197, 299, 310, 311, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +32, 33, 101, 118, 124, 134, 135, 173, 174, 175, 176, 177, 198, 199, 200, 299, 300, 310, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +32, 101, 119, 123, 134, 168, 169, 170, 171, 172, 173, 200, 201, 202, 203, 300, 310, 447, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +31, 32, 102, 119, 123, 133, 163, 164, 165, 166, 167, 204, 205, 206, 207, 208, 300, 301, 310, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +31, 102, 119, 120, 121, 122, 123, 133, 162, 163, 208, 209, 210, 211, 212, 213, 214, 301, 310, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +31, 102, 120, 121, 132, 133, 160, 161, 162, 214, 215, 216, 217, 301, 310, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +30, 31, 80, 102, 132, 157, 158, 159, 217, 218, 219, 301, 309, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +30, 80, 81, 102, 103, 131, 155, 156, 157, 220, 221, 301, 302, 309, 449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +30, 80, 81, 82, 103, 104, 130, 131, 152, 153, 154, 155, 221, 222, 223, 302, 309, 449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +30, 81, 82, 83, 104, 105, 106, 130, 149, 150, 151, 223, 302, 309, 310, 449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +29, 81, 82, 83, 84, 85, 86, 106, 107, 108, 129, 130, 147, 148, 149, 223, 302, 303, 309, 449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +29, 82, 86, 108, 109, 110, 111, 112, 128, 129, 147, 223, 303, 309, 449, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +29, 82, 83, 86, 112, 113, 114, 115, 126, 127, 128, 147, 222, 223, 303, 304, 309, 310, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +29, 83, 84, 85, 86, 115, 116, 117, 125, 126, 147, 222, 304, 310, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +29, 117, 118, 119, 123, 124, 125, 147, 148, 149, 150, 222, 304, 310, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +28, 29, 119, 120, 121, 122, 150, 151, 152, 221, 305, 310, 415, 416, 417, 418, 419, 420, 421, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +28, 152, 153, 154, 155, 221, 305, 306, 310, 415, 421, 422, 423, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +28, 76, 77, 78, 156, 157, 158, 220, 221, 306, 310, 415, 423, 424, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +28, 76, 78, 79, 158, 159, 216, 217, 218, 219, 220, 306, 310, 415, 424, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +28, 75, 76, 80, 159, 160, 161, 208, 209, 210, 211, 212, 213, 214, 215, 307, 309, 415, 416, 424, 425, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +28, 75, 81, 161, 162, 163, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 307, 309, 416, 425, 450, 0, 0, 0, 0, 0, 0, +27, 28, 75, 82, 163, 164, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 308, 309, 416, 426, 450, 0, +26, 27, 75, 81, 82, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 308, 309, 416, 427, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +26, 75, 76, 77, 79, 80, 81, 309, 416, 427, 428, 429, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +25, 26, 77, 78, 79, 416, 429, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +24, 25, 416, 429, 430, 450, 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, +24, 65, 66, 67, 68, 69, 70, 416, 430, 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +23, 63, 64, 65, 70, 415, 416, 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +22, 23, 62, 63, 70, 415, 431, 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +22, 62, 70, 414, 415, 431, 432, 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, +22, 62, 63, 64, 65, 66, 67, 68, 69, 70, 413, 414, 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +21, 412, 413, 431, 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, +21, 412, 430, 431, 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, +20, 21, 411, 412, 429, 430, 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, +20, 411, 428, 429, 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, +20, 410, 427, 428, 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, +20, 68, 69, 409, 426, 427, 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, +19, 20, 67, 68, 69, 70, 409, 424, 425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +19, 66, 67, 70, 71, 72, 409, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +19, 66, 72, 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, +19, 65, 71, 72, 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, +19, 64, 65, 71, 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, +18, 64, 70, 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, +18, 63, 69, 70, 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, +17, 18, 63, 69, 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, +17, 62, 67, 68, 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, +16, 17, 62, 66, 67, 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, +16, 62, 63, 64, 65, 66, 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, +15, 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, +14, 15, 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, +14, 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, +14, 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, +13, 14, 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, +}; diff --git a/esp32s2/videoending/main/main.c b/esp32s2/videoending/main/main.c new file mode 100644 index 0000000..647de92 --- /dev/null +++ b/esp32s2/videoending/main/main.c @@ -0,0 +1,94 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "spi_flash_mmap.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" // or "esp_efuse_custom_table.h" +#include "esp_task_wdt.h" +#include "esp_log.h" +#include "soc/dedic_gpio_reg.h" +#include "driver/gpio.h" +#include "soc/soc.h" +#include "soc/system_reg.h" +#include "soc/usb_reg.h" +#include "ulp_riscv.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "rom/gpio.h" +#include "soc/rtc.h" + +#define SOC_DPORT_USB_BASE 0x60080000 + +struct SandboxStruct +{ + void (*fnIdle)(); +}; + + +struct SandboxStruct * g_SandboxStruct; + + +void esp_sleep_enable_timer_wakeup(); + +volatile void * keep_symbols[] = { 0, vTaskDelay, ulp_riscv_halt, + ulp_riscv_timer_resume, ulp_riscv_timer_stop, ulp_riscv_load_binary, + ulp_riscv_run, ulp_riscv_config_and_run, esp_sleep_enable_timer_wakeup, + ulp_set_wakeup_period, rtc_gpio_init, rtc_gpio_set_direction, + rtc_gpio_set_level, gpio_config, gpio_matrix_out, gpio_matrix_in, + rtc_clk_cpu_freq_get_config, rtc_clk_cpu_freq_set_config_fast, + rtc_clk_apb_freq_get }; + +extern struct SandboxStruct sandbox_mode; + +void app_main(void) +{ + printf("Hello world! Keep table at %p\n", &keep_symbols ); + + g_SandboxStruct = &sandbox_mode; + + // esp_efuse_set_rom_log_scheme(ESP_EFUSE_ROM_LOG_ALWAYS_OFF); + esp_efuse_set_rom_log_scheme(ESP_EFUSE_ROM_LOG_ALWAYS_ON); + + printf("Minimum free heap size: %d bytes\n", (int)esp_get_minimum_free_heap_size()); + + void sandbox_main(); + + sandbox_main(); + + do + { + if( g_SandboxStruct && g_SandboxStruct->fnIdle ) { g_SandboxStruct->fnIdle(); } + esp_task_wdt_reset(); + taskYIELD(); + } while( 1 ); + +// printf("Restarting now.\n"); +// fflush(stdout); +// esp_restart(); +} diff --git a/esp32s2/videoending/main/siggen.h b/esp32s2/videoending/main/siggen.h new file mode 100644 index 0000000..4060027 --- /dev/null +++ b/esp32s2/videoending/main/siggen.h @@ -0,0 +1 @@ +// This file is unused in the video ending test diff --git a/esp32s2/videoending/makeending/Makefile b/esp32s2/videoending/makeending/Makefile new file mode 100644 index 0000000..3c247fd --- /dev/null +++ b/esp32s2/videoending/makeending/Makefile @@ -0,0 +1,12 @@ +IMAGEOUT:=../main/image.h + +all : $(IMAGEOUT) + +$(IMAGEOUT) : image.png imagegen + ./imagegen $< > $@ + +imagegen : imagegen.c + gcc -o $@ $^ -Os -lm + +clean : + rm -rf *.o imagegen $(IMAGEOUT) diff --git a/esp32s2/videoending/makeending/README.txt b/esp32s2/videoending/makeending/README.txt new file mode 100644 index 0000000..2096014 --- /dev/null +++ b/esp32s2/videoending/makeending/README.txt @@ -0,0 +1,4 @@ +Place a: + * Black and white (solid lines only, black background white lines, 1px wide, no grey) "image.png" file in this folder. + * I recently tested with a 461x412 pixel file so around there should be fine. + * Say `make` and it should produce `../main/image.h` from your image. diff --git a/esp32s2/videoending/makeending/imagegen.c b/esp32s2/videoending/makeending/imagegen.c new file mode 100644 index 0000000..bb3360b --- /dev/null +++ b/esp32s2/videoending/makeending/imagegen.c @@ -0,0 +1,81 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#define IMAGEOPL 32 + +int main( int argc, char ** argv ) +{ + if( argc != 2 ) + { + fprintf( stderr, "Error: Need input image file\n" ); + return -9; + } + + int w, h, n; + unsigned char *data = stbi_load( argv[1], &w, &h, &n, 1 ); + if( !data ) + { + fprintf( stderr, "Error: Failed to load image \"%s\"\n", argv[1] ); + } + int i; + printf( "#include \n" ); + printf( "\n" ); + printf( "#define IMAGEOH %d\n", h ); + printf( "#define IMAGEOPL %d\n", IMAGEOPL ); + printf( "uint16_t imageout[IMAGEOH*IMAGEOPL] = {\n" ); + int x, y; + int o; + for( y = 0; y < h; y++ ) + { + o = 0; + for( x = 0; x < w; x++ ) + { + uint8_t c = data[(x+y*w)]; + if( c > 128 ) + { + if( o < IMAGEOPL ) + { + printf( "%d, ", x ); o++; + } + else + { + fprintf( stderr, "Warning: overload on line %d\n", y ); + } + } + } + for( ; o < IMAGEOPL; o++ ) + { + printf( "0, " ); + } + printf( "\n" ); + } + printf( "};\n" ); +} + + diff --git a/esp32s2/videoending/makeending/stb_image.h b/esp32s2/videoending/makeending/stb_image.h new file mode 100644 index 0000000..5cf3c5b --- /dev/null +++ b/esp32s2/videoending/makeending/stb_image.h @@ -0,0 +1,7986 @@ +/* stb_image - v2.29 - public domain image loader - http://nothings.org/stb + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8/16-bit-per-channel + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + +LICENSE + + See end of file for license information. + +RECENT REVISION HISTORY: + + 2.29 (2023-05-xx) optimizations + 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff + 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes + 2.26 (2020-07-13) many minor fixes + 2.25 (2020-02-02) fix warnings + 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically + 2.23 (2019-08-11) fix clang static analysis warning + 2.22 (2019-03-04) gif fixes, fix warnings + 2.21 (2019-02-25) fix typo in comment + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings + 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes + 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + github:urraka (animated gif) Junggon Kim (PNM comments) + Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) + socks-the-fox (16-bit PNG) + Jeremy Sawicki (handle all ImageNet JPGs) + Optimizations & bugfixes Mikhail Morozov (1-bit BMP) + Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) + Arseny Kapoulkine Simon Breuss (16-bit PNM) + John-Mark Allen + Carmelo J Fdez-Aguera + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski + Phil Jordan Dave Moore Roy Eltham + Hayaki Saito Nathan Reed Won Chun + Luke Graham Johan Duparc Nick Verigakis the Horde3D community + Thomas Ruf Ronny Chevalier github:rlyeh + Janez Zemva John Bartholomew Michal Cichon github:romigrou + Jonathan Blow Ken Hamada Tero Hanninen github:svdijk + Eugene Golushkov Laurent Gomila Cort Stratton github:snagar + Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex + Cass Everitt Ryamond Barbiero github:grim210 + Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw + Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus + Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo + Julian Raschke Gregory Mullen Christian Floisand github:darealshinji + Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007 + Brad Weinberger Matvey Cherevko github:mosra + Luca Sas Alexander Veselov Zack Middleton [reserved] + Ryan C. Gordon [reserved] [reserved] + DO NOT ADD YOUR NAME HERE + + Jacko Dirks + + To add your name to the credits, pick a random blank space in the middle and fill it. + 80% of merge conflicts on stb PRs are due to people adding their name at the end + of the credits. +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data); +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *channels_in_file -- outputs # of image components in image file +// int desired_channels -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'desired_channels' if desired_channels is non-zero, or +// *channels_in_file otherwise. If desired_channels is non-zero, +// *channels_in_file has the number of components that _would_ have been +// output otherwise. E.g. if you set desired_channels to 4, you will always +// get RGBA output, but you can check *channels_in_file to see if it's trivially +// opaque because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *channels_in_file will be unchanged. The function +// stbi_failure_reason() can be queried for an extremely brief, end-user +// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS +// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// To query the width, height and component count of an image without having to +// decode the full file, you can use the stbi_info family of functions: +// +// int x,y,n,ok; +// ok = stbi_info(filename, &x, &y, &n); +// // returns ok=1 and sets x, y, n if image is a supported format, +// // 0 otherwise. +// +// Note that stb_image pervasively uses ints in its public API for sizes, +// including sizes of memory buffers. This is now part of the API and thus +// hard to change without causing breakage. As a result, the various image +// loaders all have certain limits on image size; these differ somewhat +// by format but generally boil down to either just under 2GB or just under +// 1GB. When the decoded image would be larger than this, stb_image decoding +// will fail. +// +// Additionally, stb_image will reject image files that have any of their +// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS, +// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit, +// the only way to have an image with such dimensions load correctly +// is for it to have a rather extreme aspect ratio. Either way, the +// assumption here is that such larger images are likely to be malformed +// or malicious. If you do need to load an image with individual dimensions +// larger than that, and it still fits in the overall size limit, you can +// #define STBI_MAX_DIMENSIONS on your own to be something larger. +// +// =========================================================================== +// +// UNICODE: +// +// If compiling for Windows and you wish to use Unicode filenames, compile +// with +// #define STBI_WINDOWS_UTF8 +// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert +// Windows wchar_t filenames to utf8. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy-to-use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// provide more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small source code footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image supports loading HDR images in general, and currently the Radiance +// .HDR file format specifically. You can still load any file through the existing +// interface; if you attempt to load an HDR file, it will be automatically remapped +// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// We optionally support converting iPhone-formatted PNGs (which store +// premultiplied BGRA) back to RGB, even though they're internally encoded +// differently. To enable this conversion, call +// stbi_convert_iphone_png_to_rgb(1). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// ADDITIONAL CONFIGURATION +// +// - You can suppress implementation of any of the decoders to reduce +// your code footprint by #defining one or more of the following +// symbols before creating the implementation. +// +// STBI_NO_JPEG +// STBI_NO_PNG +// STBI_NO_BMP +// STBI_NO_PSD +// STBI_NO_TGA +// STBI_NO_GIF +// STBI_NO_HDR +// STBI_NO_PIC +// STBI_NO_PNM (.ppm and .pgm) +// +// - You can request *only* certain decoders and suppress all other ones +// (this will be more forward-compatible, as addition of new decoders +// doesn't require you to disable them explicitly): +// +// STBI_ONLY_JPEG +// STBI_ONLY_PNG +// STBI_ONLY_BMP +// STBI_ONLY_PSD +// STBI_ONLY_TGA +// STBI_ONLY_GIF +// STBI_ONLY_HDR +// STBI_ONLY_PIC +// STBI_ONLY_PNM (.ppm and .pgm) +// +// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still +// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB +// +// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater +// than that size (in either width or height) without further processing. +// This is to let programs in the wild set an upper bound to prevent +// denial-of-service attacks on untrusted data, as one could generate a +// valid image of gigantic dimensions and force stb_image to allocate a +// huge block of memory and spend disproportionate time decoding it. By +// default this is set to (1 << 24), which is 16777216, but that's still +// very big. + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for desired_channels + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +#include +typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef STBIDEF +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +#endif + +#ifdef STBI_WINDOWS_UTF8 +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif + +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +#endif + +//////////////////////////////////// +// +// float-per-channel interface +// +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// on most compilers (and ALL modern mainstream compilers) this is threadsafe +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit (char const *filename); +STBIDEF int stbi_is_16_bit_from_file(FILE *f); +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// as above, but only applies to images loaded on the thread that calls the function +// this function is only available if your compiler supports thread-local variables; +// calling it will fail to link if your compiler doesn't +STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply); +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert); +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp, pow +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + +#ifdef __cplusplus +#define STBI_EXTERN extern "C" +#else +#define STBI_EXTERN extern +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + +#ifndef STBI_NO_THREAD_LOCALS + #if defined(__cplusplus) && __cplusplus >= 201103L + #define STBI_THREAD_LOCAL thread_local + #elif defined(__GNUC__) && __GNUC__ < 5 + #define STBI_THREAD_LOCAL __thread + #elif defined(_MSC_VER) + #define STBI_THREAD_LOCAL __declspec(thread) + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) + #define STBI_THREAD_LOCAL _Thread_local + #endif + + #ifndef STBI_THREAD_LOCAL + #if defined(__GNUC__) + #define STBI_THREAD_LOCAL __thread + #endif + #endif +#endif + +#if defined(_MSC_VER) || defined(__SYMBIAN32__) +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (-(y) & 31))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// which in turn means it gets to use SSE2 everywhere. This is unfortunate, +// but previous attempts to provide the SSE2 functions with runtime +// detection caused numerous issues. The way architecture extensions are +// exposed in GCC/Clang is, sadly, not really suited for one-file libs. +// New behavior: if compiled with -msse2, we use SSE2 without any +// detection; if not, we don't use it at all. +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#endif + +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. + return 1; +} +#endif + +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +#ifdef _MSC_VER +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name +#else +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +#ifndef STBI_MAX_DIMENSIONS +#define STBI_MAX_DIMENSIONS (1 << 24) +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + int callback_already_read; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->callback_already_read = 0; + s->img_buffer = s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + int ch; + fseek((FILE*) user, n, SEEK_CUR); + ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */ + if (ch != EOF) { + ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */ + } +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user) || ferror((FILE *) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +enum +{ + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct +{ + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__png_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__psd_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__pnm_is16(stbi__context *s); +#endif + +static +#ifdef STBI_THREAD_LOCAL +STBI_THREAD_LOCAL +#endif +const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +#ifndef STBI_NO_FAILURE_STRINGS +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} +#endif + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if (b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if (a < 0 || b < 0) return 0; + if (b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX/b; +} + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); +} +#endif + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__addsizes_valid(a*b*c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); +} +#endif + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// mallocs with size overflow checking +static void *stbi__malloc_mad2(int a, int b, int add) +{ + if (!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a*b + add); +} +#endif + +static void *stbi__malloc_mad3(int a, int b, int c, int add) +{ + if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a*b*c + add); +} + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) +static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a*b*c*d + add); +} +#endif + +// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow. +static int stbi__addints_valid(int a, int b) +{ + if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow + if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. + return a <= INT_MAX - b; +} + +// returns 1 if the product of two ints fits in a signed short, 0 on overflow. +static int stbi__mul2shorts_valid(int a, int b) +{ + if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow + if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid + if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN + return a >= SHRT_MIN / b; +} + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load_global = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_global = flag_true_if_should_flip; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global +#else +static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; + +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_local = flag_true_if_should_flip; + stbi__vertically_flip_on_load_set = 1; +} + +#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ + ? stbi__vertically_flip_on_load_local \ + : stbi__vertically_flip_on_load_global) +#endif // STBI_THREAD_LOCAL + +static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + + // test the formats with a very explicit header first (at least a FOURCC + // or distinctive magic number first) + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); + #else + STBI_NOTUSED(bpc); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); + #endif + + // then the formats that can end up attempting to load with just 1 or 2 + // bytes matching expectations; these are prone to false positives, so + // try them later + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp, ri); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi_uc *reduced; + + reduced = (stbi_uc *) stbi__malloc(img_len); + if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 *enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); + if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) +{ + int row; + size_t bytes_per_row = (size_t)w * bytes_per_pixel; + stbi_uc temp[2048]; + stbi_uc *bytes = (stbi_uc *)image; + + for (row = 0; row < (h>>1); row++) { + stbi_uc *row0 = bytes + row*bytes_per_row; + stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; + // swap row0 with row1 + size_t bytes_left = bytes_per_row; + while (bytes_left) { + size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); + memcpy(temp, row0, bytes_copy); + memcpy(row0, row1, bytes_copy); + memcpy(row1, temp, bytes_copy); + row0 += bytes_copy; + row1 += bytes_copy; + bytes_left -= bytes_copy; + } + } +} + +#ifndef STBI_NO_GIF +static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) +{ + int slice; + int slice_size = w * h * bytes_per_pixel; + + stbi_uc *bytes = (stbi_uc *)image; + for (slice = 0; slice < z; ++slice) { + stbi__vertical_flip(bytes, w, h, bytes_per_pixel); + bytes += slice_size; + } +} +#endif + +static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if (result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if (ri.bits_per_channel != 8) { + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO: move stbi__convert_format to here + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); + } + + return (unsigned char *) result; +} + +static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if (result == NULL) + return NULL; + + // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. + STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); + + if (ri.bits_per_channel != 16) { + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO: move stbi__convert_format16 to here + // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); + } + + return (stbi__uint16 *) result; +} + +#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); + } +} +#endif + +#ifndef STBI_NO_STDIO + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); +#endif + +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) + return 0; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__uint16 *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + stbi__uint16 *result; + if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f,x,y,comp,req_comp); + fclose(f); + return result; +} + + +#endif //!STBI_NO_STDIO + +STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_mem(&s,buffer,len); + + result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if (stbi__vertically_flip_on_load) { + stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); + } + + return result; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + stbi__result_info ri; + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + long pos = ftell(f); + int res; + stbi__context s; + stbi__start_file(&s,f); + res = stbi__hdr_test(&s); + fseek(f, pos, SEEK_SET); + return res; + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) +// nothing +#else +static void stbi__skip(stbi__context *s, int n) +{ + if (n == 0) return; // already there! + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) +// nothing +#else +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} +#endif + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + z += (stbi__uint32)stbi__get16le(s) << 16; + return z; +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + stbi__uint16 *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if (good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + stbi__uint16 *src = data + j * x * img_n ; + stbi__uint16 *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion"); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output; + if (!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + } + if (n < comp) { + for (i=0; i < x*y; ++i) { + output[i*comp + n] = data[i*comp + n]/255.0f; + } + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output; + if (!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi__uint16 dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0; + unsigned int code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) { + for (j=0; j < count[i]; ++j) { + h->size[k++] = (stbi_uc) (i+1); + if(k >= 257) return stbi__err("bad size list","Corrupt JPEG"); + } + } + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (~0U << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + unsigned int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + if(c < 0 || c >= 256) // symbol id out of bounds! + return -1; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing + + sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & (sgn - 1)); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static const stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0 || t > 15) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG"); + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + diff = t ? stbi__extend_receive(j, t) : 0; + + if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + data[0] = (short) (dc * (1 << j->succ_low)); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * (1 << shift)); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * (1 << shift)); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) * 4096) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0]*4; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); // consume repeated 0xff fill bytes + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4, sixteen = (p != 0); + int t = q & 15,i; + if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values! + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + L = stbi__get16be(z->s); + if (L < 2) { + if (m == 0xFE) + return stbi__err("bad COM len","Corrupt JPEG"); + else + return stbi__err("bad APP len","Corrupt JPEG"); + } + L -= 2; + + if (m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J','F','I','F','\0'}; + int ok = 1; + int i; + for (i=0; i < 5; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if (ok) + z->jfif = 1; + } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + int ok = 1; + int i; + for (i=0; i < 6; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if (ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); + return 1; + } + + return stbi__err("unknown marker","Corrupt JPEG"); +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) +{ + int i; + for (i=0; i < ncomp; ++i) { + if (z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if (z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if (z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + c = stbi__get8(s); + if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static const unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios + // and I've never seen a non-corrupted JPEG file actually use them + for (i=0; i < s->img_n; ++i) { + if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H","Corrupt JPEG"); + if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V","Corrupt JPEG"); + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if (z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + if (z->progressive) { + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if (z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j) +{ + // some JPEGs have junk at end, skip over it but if we find what looks + // like a valid marker, resume there + while (!stbi__at_eof(j->s)) { + stbi_uc x = stbi__get8(j->s); + while (x == 0xff) { // might be a marker + if (stbi__at_eof(j->s)) return STBI__MARKER_none; + x = stbi__get8(j->s); + if (x != 0x00 && x != 0xff) { + // not a stuffed zero or lead-in to another marker, looks + // like an actual marker, return it + return x; + } + // stuffed zero has x=0 now which ends the loop, meaning we go + // back to regular scan loop. + // repeated 0xff keeps trying to read the next byte of the marker. + } + } + return STBI__MARKER_none; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + j->marker = stbi__skip_jpeg_junk_at_end(j); + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + m = stbi__get_marker(j); + if (STBI__RESTART(m)) + m = stbi__get_marker(j); + } else if (stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); + m = stbi__get_marker(j); + } else { + if (!stbi__process_marker(j, m)) return 1; + m = stbi__get_marker(j); + } + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + stbi__free_jpeg_components(j, j->s->img_n, 0); +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x*y + 128; + return (stbi_uc) ((t + (t >>8)) >> 8); +} + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n, is_rgb; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; + + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if (z->s->img_n == 3 && n < 3 && !is_rgb) + decode_n = 1; + else + decode_n = z->s->img_n; + + // nothing to do if no components requested; check this now to avoid + // accessing uninitialized coutput[0] later + if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (is_rgb) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else if (z->s->img_n == 4) { + if (z->app14_color_transform == 0) { // CMYK + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], m); + out[1] = stbi__blinn_8x8(coutput[1][i], m); + out[2] = stbi__blinn_8x8(coutput[2][i], m); + out[3] = 255; + out += n; + } + } else if (z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], m); + out[1] = stbi__blinn_8x8(255 - out[1], m); + out[2] = stbi__blinn_8x8(255 - out[2], m); + out += n; + } + } else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + if (is_rgb) { + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for (i=0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } + } + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output + return output; + } +} + +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + if (!j) return stbi__errpuc("outofmem", "Out of memory"); + memset(j, 0, sizeof(stbi__jpeg)); + STBI_NOTUSED(ri); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); + if (!j) return stbi__err("outofmem", "Out of memory"); + memset(j, 0, sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); + stbi__rewind(s); + STBI_FREE(j); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + if (!j) return stbi__err("outofmem", "Out of memory"); + memset(j, 0, sizeof(stbi__jpeg)); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) +#define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[STBI__ZNSYMS]; + stbi__uint16 value[STBI__ZNSYMS]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + int hit_zeof_once; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static int stbi__zeof(stbi__zbuf *z) +{ + return (z->zbuffer >= z->zbuffer_end); +} + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + return stbi__zeof(z) ? 0 : *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + if (z->code_buffer >= (1U << z->num_bits)) { + z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ + return; + } + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s >= 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! + if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) { + if (stbi__zeof(a)) { + if (!a->hit_zeof_once) { + // This is the first time we hit eof, insert 16 extra padding btis + // to allow us to keep going; if we actually consume any of them + // though, that is invalid data. This is caught later. + a->hit_zeof_once = 1; + a->num_bits += 16; // add 16 implicit zero bits + } else { + // We already inserted our extra 16 padding bits and are again + // out, this stream is actually prematurely terminated. + return -1; + } + } else { + stbi__fill_bits(a); + } + } + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + unsigned int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (unsigned int) (z->zout - z->zout_start); + limit = old_limit = (unsigned) (z->zout_end - z->zout_start); + if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory"); + while (cur + n > limit) { + if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); + limit *= 2; + } + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static const int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static const int stbi__zlength_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static const int stbi__zdist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + if (a->hit_zeof_once && a->num_bits < 16) { + // The first time we hit zeof, we inserted 16 extra zero bits into our bit + // buffer so the decoder can just do its speculative decoding. But if we + // actually consumed any of those bits (which is the case when num_bits < 16), + // the stream actually read past the end so it is malformed. + return stbi__err("unexpected end","Corrupt PNG"); + } + return 1; + } + if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (len > a->zout_end - zout) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + int ntot = hlit + hdist; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < ntot) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else { + stbi_uc fill = 0; + if (c == 16) { + c = stbi__zreceive(a,2)+3; + if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n-1]; + } else if (c == 17) { + c = stbi__zreceive(a,3)+3; + } else if (c == 18) { + c = stbi__zreceive(a,7)+11; + } else { + return stbi__err("bad codelengths", "Corrupt PNG"); + } + if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes+n, fill, c); + n += c; + } + } + if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG"); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = +{ + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 +}; +static const stbi_uc stbi__zdefault_distance[32] = +{ + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; +/* +Init algorithm: +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} +*/ + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + a->hit_zeof_once = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , STBI__ZNSYMS)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filter used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub +}; + +static int stbi__paeth(int a, int b, int c) +{ + // This formulation looks very different from the reference in the PNG spec, but is + // actually equivalent and has favorable data dependencies and admits straightforward + // generation of branch-free code, which helps performance significantly. + int thresh = c*3 - (a + b); + int lo = a < b ? a : b; + int hi = a < b ? b : a; + int t0 = (hi <= thresh) ? lo : c; + int t1 = (thresh <= lo) ? hi : t0; + return t1; +} + +static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// adds an extra all-255 alpha channel +// dest == src is legal +// img_n must be 1 or 3 +static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n) +{ + int i; + // must process data backwards since we allow dest==src + if (img_n == 1) { + for (i=x-1; i >= 0; --i) { + dest[i*2+1] = 255; + dest[i*2+0] = src[i]; + } + } else { + STBI_ASSERT(img_n == 3); + for (i=x-1; i >= 0; --i) { + dest[i*4+3] = 255; + dest[i*4+2] = src[i*3+2]; + dest[i*4+1] = src[i*3+1]; + dest[i*4+0] = src[i*3+0]; + } + } +} + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16 ? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + stbi_uc *filter_buf; + int all_ok = 1; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + // note: error exits here don't need to clean up a->out individually, + // stbi__do_png always does on error. + if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG"); + img_len = (img_width_bytes + 1) * y; + + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, + // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), + // so just check for raw_len < img_len always. + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + + // Allocate two scan lines worth of filter workspace buffer. + filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0); + if (!filter_buf) return stbi__err("outofmem", "Out of memory"); + + // Filtering for low-bit-depth images + if (depth < 8) { + filter_bytes = 1; + width = img_width_bytes; + } + + for (j=0; j < y; ++j) { + // cur/prior filter buffers alternate + stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes; + stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes; + stbi_uc *dest = a->out + stride*j; + int nk = width * filter_bytes; + int filter = *raw++; + + // check filter type + if (filter > 4) { + all_ok = stbi__err("invalid filter","Corrupt PNG"); + break; + } + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // perform actual filtering + switch (filter) { + case STBI__F_none: + memcpy(cur, raw, nk); + break; + case STBI__F_sub: + memcpy(cur, raw, filter_bytes); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); + break; + case STBI__F_up: + for (k = 0; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); + break; + case STBI__F_avg: + for (k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); + break; + case STBI__F_paeth: + for (k = 0; k < filter_bytes; ++k) + cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0) + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes])); + break; + case STBI__F_avg_first: + memcpy(cur, raw, filter_bytes); + for (k = filter_bytes; k < nk; ++k) + cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); + break; + } + + raw += nk; + + // expand decoded bits in cur to dest, also adding an extra alpha channel if desired + if (depth < 8) { + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + stbi_uc *in = cur; + stbi_uc *out = dest; + stbi_uc inb = 0; + stbi__uint32 nsmp = x*img_n; + + // expand bits to bytes first + if (depth == 4) { + for (i=0; i < nsmp; ++i) { + if ((i & 1) == 0) inb = *in++; + *out++ = scale * (inb >> 4); + inb <<= 4; + } + } else if (depth == 2) { + for (i=0; i < nsmp; ++i) { + if ((i & 3) == 0) inb = *in++; + *out++ = scale * (inb >> 6); + inb <<= 2; + } + } else { + STBI_ASSERT(depth == 1); + for (i=0; i < nsmp; ++i) { + if ((i & 7) == 0) inb = *in++; + *out++ = scale * (inb >> 7); + inb <<= 1; + } + } + + // insert alpha=255 values if desired + if (img_n != out_n) + stbi__create_png_alpha_expand8(dest, dest, x, img_n); + } else if (depth == 8) { + if (img_n == out_n) + memcpy(dest, cur, x*img_n); + else + stbi__create_png_alpha_expand8(dest, cur, x, img_n); + } else if (depth == 16) { + // convert the image data from big-endian to platform-native + stbi__uint16 *dest16 = (stbi__uint16*)dest; + stbi__uint32 nsmp = x*img_n; + + if (img_n == out_n) { + for (i = 0; i < nsmp; ++i, ++dest16, cur += 2) + *dest16 = (cur[0] << 8) | cur[1]; + } else { + STBI_ASSERT(img_n+1 == out_n); + if (img_n == 1) { + for (i = 0; i < x; ++i, dest16 += 2, cur += 2) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = 0xffff; + } + } else { + STBI_ASSERT(img_n == 3); + for (i = 0; i < x; ++i, dest16 += 4, cur += 6) { + dest16[0] = (cur[0] << 8) | cur[1]; + dest16[1] = (cur[2] << 8) | cur[3]; + dest16[2] = (cur[4] << 8) | cur[5]; + dest16[3] = 0xffff; + } + } + } + } + } + + STBI_FREE(filter_buf); + if (!all_ok) return 0; + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); + if (!final) return stbi__err("outofmem", "Out of memory"); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, + a->out + (j*x+i)*out_bytes, out_bytes); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__unpremultiply_on_load_global = 0; +static int stbi__de_iphone_flag_global = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_global = flag_true_if_should_convert; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global +#define stbi__de_iphone_flag stbi__de_iphone_flag_global +#else +static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; +static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; + +STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; + stbi__unpremultiply_on_load_set = 1; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag_local = flag_true_if_should_convert; + stbi__de_iphone_flag_set = 1; +} + +#define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ + ? stbi__unpremultiply_on_load_local \ + : stbi__unpremultiply_on_load_global) +#define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ + ? stbi__de_iphone_flag_local \ + : stbi__de_iphone_flag_global) +#endif // STBI_THREAD_LOCAL + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + stbi_uc half = a / 2; + p[0] = (p[2] * 255 + half) / a; + p[1] = (p[1] * 255 + half) / a; + p[2] = ( t * 255 + half) / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]={0}; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); + s->img_y = stbi__get32be(s); + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + } + // even with SCAN_header, have to scan to see if we have a tRNS + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. + if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { + // header scan definitely stops at first IDAT + if (pal_img_n) + s->img_n = pal_img_n; + return 1; + } + if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } else if (has_trans) { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; + } + STBI_FREE(z->expanded); z->expanded = NULL; + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) +{ + void *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth <= 8) + ri->bits_per_channel = 8; + else if (p->depth == 16) + ri->bits_per_channel = 16; + else + return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + if (ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp, ri); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} + +static int stbi__png_is16(stbi__context *s) +{ + stbi__png p; + p.s = s; + if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) + return 0; + if (p.depth != 16) { + stbi__rewind(p.s); + return 0; + } + return 1; +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) { n += 16; z >>= 16; } + if (z >= 0x00100) { n += 8; z >>= 8; } + if (z >= 0x00010) { n += 4; z >>= 4; } + if (z >= 0x00004) { n += 2; z >>= 2; } + if (z >= 0x00002) { n += 1;/* >>= 1;*/ } + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +// extract an arbitrarily-aligned N-bit value (N=bits) +// from v, and then make it 8-bits long and fractionally +// extend it to full full range. +static int stbi__shiftsigned(unsigned int v, int shift, int bits) +{ + static unsigned int mul_table[9] = { + 0, + 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, + 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + }; + static unsigned int shift_table[9] = { + 0, 0,0,1,0,2,4,6,0, + }; + if (shift < 0) + v <<= -shift; + else + v >>= shift; + STBI_ASSERT(v < 256); + v >>= (8-bits); + STBI_ASSERT(bits >= 0 && bits <= 8); + return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; + int extra_read; +} stbi__bmp_data; + +static int stbi__bmp_set_mask_defaults(stbi__bmp_data *info, int compress) +{ + // BI_BITFIELDS specifies masks explicitly, don't override + if (compress == 3) + return 1; + + if (compress == 0) { + if (info->bpp == 16) { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } else if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + // otherwise, use defaults, which is all-0 + info->mr = info->mg = info->mb = info->ma = 0; + } + return 1; + } + return 0; // error +} + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + info->extra_read = 14; + + if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes + if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + stbi__bmp_set_mask_defaults(info, compress); + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->extra_read += 12; + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + // V4/V5 header + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs + stbi__bmp_set_mask_defaults(info, compress); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + STBI_NOTUSED(ri); + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - info.extra_read - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - info.extra_read - info.hsz) >> 2; + } + if (psize == 0) { + // accept some number of extra bytes after the header, but if the offset points either to before + // the header ends or implies a large amount of extra data, reject the file as malformed + int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); + int header_limit = 1024; // max we actually read is below 256 bytes currently. + int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. + if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { + return stbi__errpuc("bad header", "Corrupt BMP"); + } + // we established that bytes_read_so_far is positive and sensible. + // the first half of this test rejects offsets that are either too small positives, or + // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn + // ensures the number computed in the second half of the test can't overflow. + if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { + return stbi__errpuc("bad offset", "Corrupt BMP"); + } else { + stbi__skip(s, info.offset - bytes_read_so_far); + } + } + + if (info.bpp == 24 && ma == 0xff000000) + s->img_n = 3; + else + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + // sanity-check size + if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 1) width = (s->img_x + 7) >> 3; + else if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + if (info.bpp == 1) { + for (j=0; j < (int) s->img_y; ++j) { + int bit_offset = 7, v = stbi__get8(s); + for (i=0; i < (int) s->img_x; ++i) { + int color = (v>>bit_offset)&0x1; + out[z++] = pal[color][0]; + out[z++] = pal[color][1]; + out[z++] = pal[color][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + if((--bit_offset) < 0) { + bit_offset = 7; + v = stbi__get8(s); + } + } + stbi__skip(s, pad); + } + } else { + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - info.extra_read - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + unsigned int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i]; p1[i] = p2[i]; p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if (is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // fallthrough + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fallthrough + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (stbi_uc)((r * 255)/31); + out[1] = (stbi_uc)((g * 255)/31); + out[2] = (stbi_uc)((b * 255)/31); + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4] = {0}; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + STBI_NOTUSED(ri); + STBI_NOTUSED(tga_x_origin); // @TODO + STBI_NOTUSED(tga_y_origin); // @TODO + + if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + if (tga_palette_len == 0) { /* you have to have at least one entry! */ + STBI_FREE(tga_data); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + STBI_NOTUSED(tga_palette_start); + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) +{ + int count, nleft, len; + + count = 0; + while ((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + if (len > nleft) return 0; // corrupt data + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if (len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + int pixelCount; + int channelCount, compression; + int channel, i; + int bitdepth; + int w,h; + stbi_uc *out; + STBI_NOTUSED(ri); + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Check size + if (!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + + // Create the destination image. + + if (!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } else + out = (stbi_uc *) stbi__malloc(4 * w*h); + + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + if (!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + if (channel >= channelCount) { + // Fill this channel with default data. + if (bitdepth == 16 && bpc == 16) { + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for (i = 0; i < pixelCount; i++, q += 4) + *q = val; + } else { + stbi_uc *p = out+channel; + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } + } else { + if (ri->bits_per_channel == 16) { // output bpc + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + for (i = 0; i < pixelCount; i++, q += 4) + *q = (stbi__uint16) stbi__get16be(s); + } else { + stbi_uc *p = out+channel; + if (bitdepth == 16) { // input bpc + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + } + + // remove weird white matte from PSD + if (channelCount >= 4) { + if (ri->bits_per_channel == 16) { + for (i=0; i < w*h; ++i) { + stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; + if (pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); + pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); + pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + } + } + } else { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + } + + // convert to desired output format + if (req_comp && req_comp != 4) { + if (ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) +{ + stbi_uc *result; + int i, x,y, internal_comp; + STBI_NOTUSED(ri); + + if (!comp) comp = &internal_comp; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + + if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); + if (!result) return stbi__errpuc("outofmem", "Out of memory"); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + stbi_uc *background; // The current "background" as far as a gif is concerned + stbi_uc *history; + int flags, bgindex, ratio, transparent, eflags; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[8192]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; + int delay; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)"); + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!g) return stbi__err("outofmem", "Out of memory"); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + int idx; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + idx = g->cur_x + g->cur_y; + p = &g->out[idx]; + g->history[idx / 4] = 1; + + c = &g->color_table[g->codes[code].suffix * 4]; + if (c[3] > 128) { // don't render transparent pixels; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) { + return stbi__errpuc("no clear code", "Corrupt GIF"); + } + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 8192) { + return stbi__errpuc("too many codes", "Corrupt GIF"); + } + + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +// two back is the image from two frames ago, used for a very specific disposal format +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) +{ + int dispose; + int first_frame; + int pi; + int pcount; + STBI_NOTUSED(req_comp); + + // on first frame, any non-written pixels get the background colour (non-transparent) + first_frame = 0; + if (g->out == 0) { + if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) + return stbi__errpuc("too large", "GIF image is too large"); + pcount = g->w * g->h; + g->out = (stbi_uc *) stbi__malloc(4 * pcount); + g->background = (stbi_uc *) stbi__malloc(4 * pcount); + g->history = (stbi_uc *) stbi__malloc(pcount); + if (!g->out || !g->background || !g->history) + return stbi__errpuc("outofmem", "Out of memory"); + + // image is treated as "transparent" at the start - ie, nothing overwrites the current background; + // background colour is only used for pixels that are not rendered first frame, after that "background" + // color refers to the color that was there the previous frame. + memset(g->out, 0x00, 4 * pcount); + memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) + memset(g->history, 0x00, pcount); // pixels that were affected previous frame + first_frame = 1; + } else { + // second frame - how do we dispose of the previous one? + dispose = (g->eflags & 0x1C) >> 2; + pcount = g->w * g->h; + + if ((dispose == 3) && (two_back == 0)) { + dispose = 2; // if I don't have an image to revert back to, default to the old background + } + + if (dispose == 3) { // use previous graphic + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); + } + } + } else if (dispose == 2) { + // restore what was changed last frame to background before that frame; + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); + } + } + } else { + // This is a non-disposal case eithe way, so just + // leave the pixels as is, and they will become the new background + // 1: do not dispose + // 0: not specified. + } + + // background is what out is after the undoing of the previou frame; + memcpy( g->background, g->out, 4 * g->w * g->h ); + } + + // clear my history; + memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + + for (;;) { + int tag = stbi__get8(s); + switch (tag) { + case 0x2C: /* Image Descriptor */ + { + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + // if the width of the specified rectangle is 0, that means + // we may not see *any* pixels or the image is malformed; + // to make sure this is caught, move the current y down to + // max_y (which is what out_gif_code checks). + if (w == 0) + g->cur_y = g->max_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (!o) return NULL; + + // if this was the first frame, + pcount = g->w * g->h; + if (first_frame && (g->bgindex > 0)) { + // if first frame, any pixel not drawn to gets the background color + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi] == 0) { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); + } + } + } + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + int ext = stbi__get8(s); + if (ext == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 255; + } + if (g->eflags & 0x01) { + g->transparent = stbi__get8(s); + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 0; + } + } else { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) { + stbi__skip(s, len); + } + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } +} + +static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays) +{ + STBI_FREE(g->out); + STBI_FREE(g->history); + STBI_FREE(g->background); + + if (out) STBI_FREE(out); + if (delays && *delays) STBI_FREE(*delays); + return stbi__errpuc("outofmem", "Out of memory"); +} + +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + if (stbi__gif_test(s)) { + int layers = 0; + stbi_uc *u = 0; + stbi_uc *out = 0; + stbi_uc *two_back = 0; + stbi__gif g; + int stride; + int out_size = 0; + int delays_size = 0; + + STBI_NOTUSED(out_size); + STBI_NOTUSED(delays_size); + + memset(&g, 0, sizeof(g)); + if (delays) { + *delays = 0; + } + + do { + u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + + if (u) { + *x = g.w; + *y = g.h; + ++layers; + stride = g.w * g.h * 4; + + if (out) { + void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); + if (!tmp) + return stbi__load_gif_main_outofmem(&g, out, delays); + else { + out = (stbi_uc*) tmp; + out_size = layers * stride; + } + + if (delays) { + int *new_delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers ); + if (!new_delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + *delays = new_delays; + delays_size = layers * sizeof(int); + } + } else { + out = (stbi_uc*)stbi__malloc( layers * stride ); + if (!out) + return stbi__load_gif_main_outofmem(&g, out, delays); + out_size = layers * stride; + if (delays) { + *delays = (int*) stbi__malloc( layers * sizeof(int) ); + if (!*delays) + return stbi__load_gif_main_outofmem(&g, out, delays); + delays_size = layers * sizeof(int); + } + } + memcpy( out + ((layers - 1) * stride), u, stride ); + if (layers >= 2) { + two_back = out - 2 * stride; + } + + if (delays) { + (*delays)[layers - 1U] = g.delay; + } + } + } while (u != 0); + + // free temp buffer; + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + + // do the final conversion after loading everything; + if (req_comp && req_comp != 4) + out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); + + *z = layers; + return out; + } else { + return stbi__errpuc("not GIF", "Image was not as a gif type."); + } +} + +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *u = 0; + stbi__gif g; + memset(&g, 0, sizeof(g)); + STBI_NOTUSED(ri); + + u = stbi__gif_load_next(s, &g, comp, req_comp, 0); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + + // moved conversion to after successful load so that the same + // can be done for multiple frames. + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g.w, g.h); + } else if (g.out) { + // if there was an error and we allocated an image buffer, free it! + STBI_FREE(g.out); + } + + // free buffers needed for multiple frame loading; + STBI_FREE(g.history); + STBI_FREE(g.background); + + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s, const char *signature) +{ + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + stbi__rewind(s); + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); + stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + const char *headerToken; + STBI_NOTUSED(ri); + + // Check identifier + headerToken = stbi__hdr_gettoken(s,buffer); + if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); + if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)"); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + + // Read data + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if (!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if (!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } + + for (k = 0; k < 4; ++k) { + int nleft; + i = 0; + while ((nleft = width - i) > 0) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + if (scanline) + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int dummy; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + if (p == NULL) { + stbi__rewind( s ); + return 0; + } + if (x) *x = s->img_x; + if (y) *y = s->img_y; + if (comp) { + if (info.bpp == 24 && info.ma == 0xff000000) + *comp = 3; + else + *comp = info.ma ? 4 : 3; + } + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount, dummy, depth; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 8 && depth != 16) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi__psd_is16(stbi__context *s) +{ + int channelCount, depth; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + STBI_NOTUSED(stbi__get32be(s)); + STBI_NOTUSED(stbi__get32be(s)); + depth = stbi__get16be(s); + if (depth != 16) { + stbi__rewind( s ); + return 0; + } + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained,dummy; + stbi__pic_packet packets[10]; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + STBI_NOTUSED(ri); + + ri->bits_per_channel = stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n); + if (ri->bits_per_channel == 0) + return 0; + + if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + + if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) { + STBI_FREE(out); + return stbi__errpuc("bad PNM", "PNM file truncated"); + } + + if (req_comp && req_comp != s->img_n) { + if (ri->bits_per_channel == 16) { + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y); + } else { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + } + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + if((value > 214748364) || (value == 214748364 && *c > '7')) + return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int"); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv, dummy; + char c, p, t; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + stbi__rewind(s); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind(s); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + if(*x == 0) + return stbi__err("invalid width", "PPM image header had zero or overflowing width"); + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + if (*y == 0) + return stbi__err("invalid width", "PPM image header had zero or overflowing width"); + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + if (maxv > 65535) + return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); + else if (maxv > 255) + return 16; + else + return 8; +} + +static int stbi__pnm_is16(stbi__context *s) +{ + if (stbi__pnm_info(s, NULL, NULL, NULL) == 16) + return 1; + return 0; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +static int stbi__is_16_main(stbi__context *s) +{ + #ifndef STBI_NO_PNG + if (stbi__png_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_is16(s)) return 1; + #endif + return 0; +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} + +STBIDEF int stbi_is_16_bit(char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; +} + +STBIDEF int stbi_is_16_bit_from_file(FILE *f) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__is_16_main(&s); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__is_16_main(&s); +} + +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__is_16_main(&s); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug + 1-bit BMP + *_is_16_bit api + avoid warnings + 2.16 (2017-07-23) all functions have 16-bit variants; + STBI_NO_STDIO works again; + compilation fixes; + fix rounding in unpremultiply; + optimize vertical flip; + disable raw_len validation; + documentation fixes + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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/esp32s2/videoending/partitions.csv b/esp32s2/videoending/partitions.csv new file mode 100644 index 0000000..209e1e3 --- /dev/null +++ b/esp32s2/videoending/partitions.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +# Note: if you change the size of the nvs partition, make sure to update NVS_PARTITION_SIZE in `components/hdw-nvs/nvs_manager.h` +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +storage, data, spiffs, , 0xF0000, diff --git a/esp32s2/videoending/sdkconfig b/esp32s2/videoending/sdkconfig new file mode 100644 index 0000000..2645b80 --- /dev/null +++ b/esp32s2/videoending/sdkconfig @@ -0,0 +1,1810 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.1.1 Project Configuration +# +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_CP_DMA_SUPPORTED=y +CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SUPPORTS_SECURE_DL_MODE=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_RISCV_COPROC_SUPPORTED=y +CONFIG_SOC_USB_OTG_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED=y +CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD=y +CONFIG_SOC_TEMP_SENSOR_SUPPORTED=y +CONFIG_SOC_CACHE_SUPPORT_WRAP=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_PSRAM_DMA_CAPABLE=y +CONFIG_SOC_XT_WDT_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SYSTIMER_SUPPORTED=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_HMAC_SUPPORTED=y +CONFIG_SOC_DIG_SIGN_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_MEMPROT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_ARBITER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED=y +CONFIG_SOC_ADC_MONITOR_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=32 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_IIR_FILTER_NUM=2 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=83333 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=611 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=13 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=13 +CONFIG_SOC_ADC_CALIBRATION_V1_SUPPORTED=y +CONFIG_SOC_ADC_SELF_HW_CALI_SUPPORTED=y +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y +CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED=y +CONFIG_SOC_CP_DMA_MAX_BUFFER_SIZE=4095 +CONFIG_SOC_CPU_CORES_NUM=1 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=47 +CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER=y +CONFIG_SOC_GPIO_FILTER_CLK_SUPPORT_APB=y +CONFIG_SOC_GPIO_SUPPORT_RTC_INDEPENDENT=y +CONFIG_SOC_GPIO_SUPPORT_FORCE_HOLD=y +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0x7FFFFFFFFFFF +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x00007FFFFC000000 +CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_ALLOW_REG_ACCESS=y +CONFIG_SOC_DEDIC_GPIO_HAS_INTERRUPT=y +CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_HW_CLR_BUS=y +CONFIG_SOC_I2C_SUPPORT_REF_TICK=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2S_NUM=1 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_DMA_EQUAL=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_APLL_MIN_FREQ=250000000 +CONFIG_SOC_I2S_APLL_MAX_FREQ=500000000 +CONFIG_SOC_I2S_APLL_MIN_RATE=10675 +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=1 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 +CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=5 +CONFIG_SOC_MMU_PERIPH_NUM=1 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=4 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=4 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y +CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y +CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y +CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y +CONFIG_SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY=y +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=22 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=3 +CONFIG_SOC_SPI_MAX_CS_NUM=6 +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=72 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_SPI_SUPPORT_DDRCLK=y +CONFIG_SOC_SPI_SLAVE_SUPPORT_SEG_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CD_SIG=y +CONFIG_SOC_SPI_SUPPORT_CONTINUOUS_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2=y +CONFIG_SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT=y +CONFIG_SOC_MEMSPI_IS_INDEPENDENT=y +CONFIG_SOC_SPI_SUPPORT_OCT=y +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_SYSTIMER_COUNTER_NUM=y +CONFIG_SOC_SYSTIMER_ALARM_NUM=3 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_HI=32 +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TOUCH_VERSION_2=y +CONFIG_SOC_TOUCH_SENSOR_NUM=15 +CONFIG_SOC_TOUCH_PROXIMITY_CHANNEL_NUM=3 +CONFIG_SOC_TOUCH_PAD_THRESHOLD_MAX=0x1FFFFF +CONFIG_SOC_TOUCH_PAD_MEASURE_WAIT_MAX=0xFF +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_BRP_MAX=32768 +CONFIG_SOC_TWAI_SUPPORTS_RX_STATUS=y +CONFIG_SOC_UART_NUM=2 +CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPIRAM_XIP_SUPPORTED=y +CONFIG_SOC_USB_PERIPH_NUM=y +CONFIG_SOC_SHA_DMA_MAX_BUFFER_SIZE=3968 +CONFIG_SOC_SHA_SUPPORT_DMA=y +CONFIG_SOC_SHA_SUPPORT_RESUME=y +CONFIG_SOC_SHA_CRYPTO_DMA=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA224=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_SHA_SUPPORT_SHA512_224=y +CONFIG_SOC_SHA_SUPPORT_SHA512_256=y +CONFIG_SOC_SHA_SUPPORT_SHA512_T=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_DMA=y +CONFIG_SOC_AES_SUPPORT_GCM=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_DCACHE=y +CONFIG_SOC_EFUSE_HARD_DIS_JTAG=y +CONFIG_SOC_EFUSE_SOFT_DIS_JTAG=y +CONFIG_SOC_EFUSE_DIS_BOOT_REMAP=y +CONFIG_SOC_EFUSE_DIS_LEGACY_SPI_BOOT=y +CONFIG_SOC_EFUSE_DIS_ICACHE=y +CONFIG_SOC_SECURE_BOOT_V2_RSA=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=3 +CONFIG_SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=64 +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_256=y +CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 +CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE=4 +CONFIG_SOC_AES_CRYPTO_DMA=y +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH=12 +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_APLL_MULTIPLIER_OUT_MIN_HZ=350000000 +CONFIG_SOC_APLL_MULTIPLIER_OUT_MAX_HZ=500000000 +CONFIG_SOC_APLL_MIN_HZ=5303031 +CONFIG_SOC_APLL_MAX_HZ=125000000 +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_COEX_HW_PTI=y +CONFIG_SOC_EXTERNAL_COEX_LEADER_TX_LINE=y +CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC=y +CONFIG_SOC_WIFI_HW_TSF=y +CONFIG_SOC_WIFI_FTM_SUPPORT=y +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32s2" +CONFIG_IDF_TARGET_ESP32S2=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0002 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# end of Build type + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=0 +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +# CONFIG_BOOTLOADER_WDT_ENABLE is not set +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y +CONFIG_SECURE_BOOT_V2_PREFERRED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +CONFIG_SECURE_ROM_DL_MODE_ENABLED=y +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_REGI2C_BUG=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG=y + +# +# Boot ROM Behavior +# +CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y +# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set +# end of Boot ROM Behavior + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +# CONFIG_ESPTOOLPY_BEFORE_RESET is not set +CONFIG_ESPTOOLPY_BEFORE_NORESET=y +CONFIG_ESPTOOLPY_BEFORE="no_reset" +# CONFIG_ESPTOOLPY_AFTER_RESET is not set +CONFIG_ESPTOOLPY_AFTER_NORESET=y +CONFIG_ESPTOOLPY_AFTER="no_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +CONFIG_COMPILER_OPTIMIZATION_PERF=y +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Driver Configurations +# + +# +# Legacy ADC Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Configuration + +# +# SPI Configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI Configuration + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Temperature sensor Configuration +# +# CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set +# end of Temperature sensor Configuration + +# +# UART Configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART Configuration + +# +# GPIO Configuration +# +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of GPIO Configuration + +# +# Sigma Delta Modulator Configuration +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of Sigma Delta Modulator Configuration + +# +# GPTimer Configuration +# +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of GPTimer Configuration + +# +# PCNT Configuration +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of PCNT Configuration + +# +# RMT Configuration +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of RMT Configuration + +# +# I2S Configuration +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of I2S Configuration + +# +# DAC Configuration +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +# end of DAC Configuration +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# Ethernet +# +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +# CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32S2_REV_MIN_0=y +# CONFIG_ESP32S2_REV_MIN_1 is not set +CONFIG_ESP32S2_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32-S2 Revision (Rev v1.99) +# +CONFIG_ESP32S2_REV_MAX_FULL=199 +CONFIG_ESP_REV_MAX_FULL=199 +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO=y +# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND is not set +# CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=576 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +CONFIG_XTAL_FREQ_40=y +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=15 +CONFIG_ESP_PHY_MAX_TX_POWER=15 +CONFIG_ESP_PHY_REDUCE_TX_POWER=y +# CONFIG_ESP_PHY_ENABLE_USB is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP PSRAM +# +CONFIG_SPIRAM=y + +# +# SPI RAM config +# +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_TYPE_AUTO=y +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_CLK_IO=30 +CONFIG_SPIRAM_CS_IO=26 +# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set +# CONFIG_SPIRAM_RODATA is not set +CONFIG_SPIRAM_SPEED_80M=y +# CONFIG_SPIRAM_SPEED_40M is not set +# CONFIG_SPIRAM_SPEED_26M is not set +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM_SPEED=80 +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +# CONFIG_SPIRAM_USE_MEMMAP is not set +CONFIG_SPIRAM_USE_CAPS_ALLOC=y +# CONFIG_SPIRAM_USE_MALLOC is not set +CONFIG_SPIRAM_MEMTEST=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# end of SPI RAM config +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 + +# +# Cache config +# +CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set +# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y +CONFIG_ESP32S2_DATA_CACHE_8KB=y +# CONFIG_ESP32S2_DATA_CACHE_16KB is not set +# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set +# end of Cache config + +# +# Memory +# +# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32S2_TRAX is not set +CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +# CONFIG_ESP_SYSTEM_MEMPROT_FEATURE is not set +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_CDC is not set +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_TASK_WDT_EN=y +# CONFIG_ESP_TASK_WDT_INIT is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=7 +# end of Brownout Detector + +# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 +# end of IPC (Inter-Processor Call) + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY=0x1 +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_TX_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +# CONFIG_ESP_WIFI_SOFTAP_SUPPORT is not set +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_SUITE_B_192 is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +CONFIG_FREERTOS_UNICORE=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# end of Port + +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +CONFIG_IEEE802154_CCA_THRESHOLD=-60 +CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 + +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=0 +# CONFIG_LOG_COLORS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +# CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES is not set +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_TIMERS_ONDEMAND is not set +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +# CONFIG_LWIP_SO_REUSE is not set +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +# CONFIG_LWIP_IP4_FRAG is not set +# CONFIG_LWIP_IP4_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +# CONFIG_LWIP_DHCP_DOES_ARP_CHECK is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +# CONFIG_LWIP_DHCPS is not set +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +# CONFIG_LWIP_NETIF_LOOPBACK is not set + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +# CONFIG_LWIP_WND_SCALE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +# CONFIG_LWIP_ESP_LWIP_ASSERT is not set + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +# CONFIG_MBEDTLS_HAVE_TIME is not set +# CONFIG_MBEDTLS_ECDSA_DETERMINISTIC is not set +# CONFIG_MBEDTLS_SHA512_C is not set +# CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT is not set +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +CONFIG_MBEDTLS_TLS_DISABLED=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +# CONFIG_MQTT_PROTOCOL_311 is not set +# CONFIG_MQTT_PROTOCOL_5 is not set +# CONFIG_MQTT_TRANSPORT_SSL is not set +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# Thread Operational Dataset +# +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" +CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 +CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" +CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" +# end of Thread Operational Dataset +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=1024 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y +# CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_GD_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +# CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE is not set +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +# CONFIG_WS_TRANSPORT is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +CONFIG_ULP_COPROC_ENABLED=y +# CONFIG_ULP_COPROC_TYPE_FSM is not set +CONFIG_ULP_COPROC_TYPE_RISCV=y +CONFIG_ULP_COPROC_RESERVE_MEM=8168 + +# +# ULP RISC-V Settings +# +CONFIG_ULP_RISCV_UART_BAUDRATE=9600 +CONFIG_ULP_RISCV_I2C_RW_TIMEOUT=500 +# end of ULP RISC-V Settings +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +# CONFIG_UNITY_ENABLE_FLOAT is not set +# CONFIG_UNITY_ENABLE_DOUBLE is not set +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +# CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER is not set +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# USB-OTG +# +CONFIG_USB_OTG_SUPPORTED=y +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 +CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y +# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set +# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# +# Root Hub configuration +# +CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 +CONFIG_USB_HOST_RESET_HOLD_MS=30 +CONFIG_USB_HOST_RESET_RECOVERY_MS=30 +CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 +# end of Root Hub configuration +# end of USB-OTG + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION=y +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32S2_NO_BLOBS is not set +CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=0 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_EXTERNAL_COEX_ENABLE is not set +# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_OTA_ALLOW_HTTP is not set +CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=15 +CONFIG_ESP32_PHY_MAX_TX_POWER=15 +CONFIG_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +CONFIG_DEFAULT_PSRAM_CLK_IO=30 +CONFIG_DEFAULT_PSRAM_CS_IO=26 +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ=240 +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y +# CONFIG_ESP32S2_MEMPROT_FEATURE is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=8192 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +# CONFIG_TASK_WDT is not set +# CONFIG_ESP_TASK_WDT is not set +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S2_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32S2_BROWNOUT_DET=y +CONFIG_ESP32S2_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_7=y +CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S2_BROWNOUT_DET_LVL=7 +CONFIG_IPC_TASK_STACK_SIZE=1536 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED is not set +# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_ESP_GRATUITOUS_ARP is not set +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_SYSTIMER=y +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RISCV=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=8168 +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/esp8266/esp8266_i2s_setup.h b/esp8266/esp8266_i2s_setup.h new file mode 100644 index 0000000..96b8fda --- /dev/null +++ b/esp8266/esp8266_i2s_setup.h @@ -0,0 +1,134 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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. +*/ + +#ifndef _ESP8266_I2S_SETUP +#define _ESP8266_I2S_SETUP + +#include "slc_register.h" +#include "dmastuff.h" + +/* Need something like: + + #define DMABUFFERDEPTH 3 + #define WS_I2S_BCK SPI_DIV //Can't be less than 1. + #define WS_I2S_DIV 1 + +*/ + +static struct sdio_queue i2sBufDescTX[DMABUFFERDEPTH] __attribute__((aligned(128)));; + +void slc_isr(void * v); + +static void testi2s_init( uint32_t * initial_data ); + +//Initialize I2S subsystem for DMA circular buffer use +static void testi2s_init( uint32_t * default_data ) { + int x, y; + //Bits are shifted out + + //Initialize DMA buffer descriptors in such a way that they will form a circular + //buffer. + + for (x=0; x compilecount.txt | true Compiled $(COMPILECOUNT) times +CFLAGS=-I../../lib -I.. + +include ../nosdk8266/Makefile + +rf_data_gen : rf_data_gen.c + gcc -o $@ $^ -lm -DMAIN_MHZ=$(MAIN_MHZ) + +chirpbuffinfo.h : chirpbuff.dat + +teststrap : main.c chirpbuff.dat + gcc -o teststrap main.c -DTESTSTRAP -I../nosdk8266/include + + +chirpbuff.dat : rf_data_gen + ./rf_data_gen + +chirpbuff.dat.flash : chirpbuff.dat + $(ESPUTIL) -b 115200 flash 0x20000 chirpbuff.dat + +cleanall : clean + rm -rf chirpbuff.h rf_data_gen chirpbuff.dat chirpbuffinfo.h + diff --git a/esp8266/example_125k_raw/README.md b/esp8266/example_125k_raw/README.md new file mode 100644 index 0000000..61f35d6 --- /dev/null +++ b/esp8266/example_125k_raw/README.md @@ -0,0 +1,6 @@ +# ESP8266 / ESP8285 Lora Transmitter + +Connect a small length of wire to the "RX" pin on your ESP8266, then it will transmit SF7 LoRa messages at 904.1MHz. + +This is designed to work at 173MHz, but, you can set `MAIN_MHZ=80` in the Makefile, and run it without any overclocking. + diff --git a/esp8266/example_125k_raw/compilecount.txt b/esp8266/example_125k_raw/compilecount.txt new file mode 100644 index 0000000..ea90ee3 --- /dev/null +++ b/esp8266/example_125k_raw/compilecount.txt @@ -0,0 +1 @@ +45 diff --git a/esp8266/example_125k_raw/main.c b/esp8266/example_125k_raw/main.c new file mode 100644 index 0000000..4be3f34 --- /dev/null +++ b/esp8266/example_125k_raw/main.c @@ -0,0 +1,378 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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. + +**/ + +// This was my first test, it still contains a number of TESTSTRAP flags. +// Teststrap was used when I compiled and ran this code on a host PC. +// In general, don't use this, code is just left around in case I run into +// any really weird bugs. +#ifdef TESTSTRAP + +#include +#include +#include "chirpbuff.h" +#include + +#define uint32 uint32_t + +#else + +#include "esp8266_auxrom.h" +#include "eagle_soc.h" +#include "nosdk8266.h" +#include "esp8266_rom.h" + +// TODO: Use float number (related to 8) to fix the drift +#define call_delay_us(time) { asm volatile("mov.n a2, %0\n_call0 delay4clk" : : "r"(time * (MAIN_MHZ / 8)) : "a2" ); } + +#include "ets_sys.h" +#include "pin_mux_register.h" + +#endif + +#include "slc_register.h" +#include "dmastuff.h" +#include "chirpbuffinfo.h" +#include "LoRa-SDR-Code.h" + +#define DMABUFFERDEPTH 3 +//These contol the speed at which the bus comms. +#define WS_I2S_BCK SPI_DIV //Can't be less than 1. +#define WS_I2S_DIV 1 + +#ifndef TESTSTRAP +#include "esp8266_i2s_setup.h" +#endif + +uint32_t chirpbuffUP[CHIRPLENGTH_WORDS_WITH_PADDING]; +uint32_t chirpbuffDOWN[CHIRPLENGTH_WORDS_WITH_PADDING]; +uint32_t dummy[DMA_SIZE_WORDS]; + +volatile int fxcycle; +int etx; + +// Limit because of RAM usage, but this should be able to hold a practical limit of a 255 byte LoRa packet. +#define MAX_SYMBOLS 532 + + +// Our table is bespoke for the specific SF. +#define CHIPSSPREAD CHIRPLENGTH_WORDS// QUARTER_CHIRP_LENGTH_WORDS (TODO: Use the quater value elsewhere in the code) +#define MARK_FROM_SF0 (1< We should check to make sure we are SLC_RX_EOF_INT_ST, but we are only getting one interrupt. +#ifdef TESTSTRAP + struct sdio_queue tmp; + finishedDesc = &tmp; +#else + WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff); + finishedDesc=(struct sdio_queue*)READ_PERI_REG(SLC_RX_EOF_DES_ADDR); +#endif + + etx++; + + if( quadsetplace < 0 ) + { + goto dump0; + } + + // LoRa symbols are in quarters of a chirp. + if( fxcycle>= NUM_DMAS_PER_QUARTER_CHIRP ) + { + fxcycle = 0; + quadsetplace++; + if( quadsetplace >= quadsetcount ) goto dump0; + } + + int symbol = quadsets[quadsetplace]; + + // Select down- or up-chirp. + if( symbol < 0 ) + { + int word = fxcycle * DMA_SIZE_WORDS - symbol - 1; + if( word >= CHIPSSPREAD ) word -= CHIPSSPREAD; + word++; + sendbuff = (chirpbuffDOWN + word); + } + else + { + int word = fxcycle * DMA_SIZE_WORDS + symbol; + if( word >= CHIPSSPREAD ) word -= CHIPSSPREAD; + sendbuff = (chirpbuffUP + word); + } + +#ifndef FOUND_PERFECT_DIVISOR + // Sometimes we do the full length, of all of the needed DMAs + // Sometimes we overshoot the time window, so we peel off 4 bytes. + // + // Very few combinations of clock rate, divisor, etc can produce + // perfect divisors. Most notably 52MHz, /2 SF9 can produce a perfect + // divisor. While this is very tidy and beautiful that the + // words would align perfectly, the actual difference it makes on + // LoRa's ability to receive the message is minimal. + // + // Additionally, 80MHz /2 SF7 can produce a perfect divisor. + int running_bits_after = runningcount_bits + DMA_SIZE_WORDS*32; + int overflow = running_bits_after - IDEAL_QUARTER_CHIRP_LENGTH_BITS; + if( overflow >= 0 ) + { + int overflow_amount = overflow / 32; + int overflow_remainder = overflow % 32; + sendlen = DMA_SIZE_WORDS*4 - 4*overflow_amount; + runningcount_bits = overflow_remainder; + + // XXX TODO: Why can't I put the logic for advancing the group in here? + } + else + { + sendlen = DMA_SIZE_WORDS*4; + runningcount_bits = running_bits_after; + } +#else + sendlen = DMA_SIZE_WORDS*4; +#endif + +#ifdef TESTSTRAP + static FILE * fappendlog; + if( !fappendlog ) fappendlog = fopen( "fappendlog.csv", "w" ); + { + if( symbol < 0 ) + fprintf( fappendlog, "2, %d, %d\n", (int)(CHIRPLENGTH_WORDS - (sendbuff - chirpbuffDOWN) - 1), sendlen ); + else + fprintf( fappendlog, "1, %d, %d\n", (int)(sendbuff - chirpbuffUP), sendlen ); + } +#else + finishedDesc->buf_ptr = (uint32_t)sendbuff; + finishedDesc->datalen = sendlen; +#endif + + fxcycle++; + return; + + +dump0: +#ifdef TESTSTRAP + printf( "Hit dummy %d %d\n", quadsetplace, quadsetcount ); + exit( 0 ); +#else + // This location just always reads as zeroes. + finishedDesc->buf_ptr = (uint32_t)dummy; + quadsetplace = -1; +#endif + return; +} + + +#ifdef TESTSTRAP + +void SPIRead( uint32_t pos, uint32_t * buff, int len ) +{ + memcpy( buff, (pos - 0x00020000) + (uint8_t*)chirpbuff, len ); +} + +void nosdk8266_init() +{ +} + + +void testi2s_init( uint32_t * default_address ) +{ +} + +#endif + +int main() +{ + // We store the bit pattern at flash:0x20000, so we don't have to constantly + // re-write it when working on code. + SPIRead( MEMORY_START_OFFSET_BYTES, chirpbuffUP, sizeof( chirpbuffUP ) ); + SPIRead( REVERSE_START_OFFSET_BYTES, chirpbuffDOWN, sizeof( chirpbuffDOWN ) ); + memset( dummy, 0, sizeof( dummy ) ); + + // Don't crank up clock speed til we're done with flash. + nosdk8266_init(); + + + int i = 0; + fxcycle = 0; + etx = 0; + + +#ifndef TESTSTRAP + // Configure GPIO5 (TX) and GPIO2 (LED) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5); + PIN_DIR_OUTPUT = _BV(2); //Enable GPIO2 light off. + + // Run the I2S bus at 1040/6 = 173.333 MHz. + // It looks like, at least on my part, if I try running + // hotter it can get to 1040/5.1 but not all the way to + // 5 so it's unstable there. +#endif + testi2s_init( dummy ); + + int frame = 0; + uint16_t lora_symbols[MAX_SYMBOLS]; + int lora_symbols_count; + + while(1) { + //12x this speed. + frame++; +#ifndef TESTSTRAP + PIN_OUT_SET = _BV(2); //Turn GPIO2 light off. + //call_delay_us(1000000); + printf("ETX: %d %08x\n", fxcycle, chirpbuffUP[10] ); + PIN_OUT_CLEAR = _BV(2); //Turn GPIO2 light off. + call_delay_us(500000); +#endif + call_delay_us(2000000); + + // Just some random data. + uint8_t payload_in[259] = { 0xbb, 0xcc, 0xde, 0x55, 0x22,}; + int payload_in_size = 6; + + static int msgno = 0; + payload_in[4] = msgno++; + + lora_symbols_count = 0; + int r = CreateMessageFromPayload( lora_symbols, &lora_symbols_count, MAX_SYMBOLS, SF_NUMBER, 4, payload_in, payload_in_size ); + + if( r < 0 ) + { + printf( "Failed to generate message (%d)\n", r ); + // Failed + continue; + } + + int j; + + quadsetcount = 0; + int32_t * qso = quadsets; + for( j = 0; j < PREAMBLE_CHIRPS; j++ ) + { + qso = AddChirp( qso, 0, 0 ); + } + + uint8_t syncword = 0x43; + + #if SF_NUMBER == 6 + #define CODEWORD_SHIFT 2 + #else + #define CODEWORD_SHIFT 3 + #endif + + if( CODEWORD_LENGTH > 0 ) + qso = AddChirp( qso, ( ( syncword & 0xf ) << CODEWORD_SHIFT ), 0 ); + if( CODEWORD_LENGTH > 1 ) + qso = AddChirp( qso, ( ( ( syncword & 0xf0 ) >> 4 ) << CODEWORD_SHIFT ), 0); + + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + + if( SF_NUMBER <= 6 ) + { + // Two additional upchirps with SF6 https://github.com/tapparelj/gr-lora_sdr/issues/74#issuecomment-1891569580 + for( j = 0; j < 2; j++ ) + qso = AddChirp( qso, 0, 0 ); + } + + for( j = 0; j < lora_symbols_count; j++ ) + { + int ofs = lora_symbols[j]; + //ofs = ofs ^ ((MARK_FROM_SF6<<6) -1); + //ofs &= (MARK_FROM_SF6<<6) -1; + qso = AddChirp( qso, ofs, 0 ); + printf( "%02x ", ofs ); + } + printf( "\n" ); + + runningcount_bits = 0; + + // This tells the interrupt we have data. + quadsetcount = qso - quadsets + 0; + printf( "--- %d [%d] %d\n", lora_symbols_count, quadsetcount, CHIPSSPREAD/4 ); + quadsetplace = 0; +#ifdef TESTSTRAP + while(1) + { + slc_isr( 0 ); + } +#endif + } + +} + diff --git a/esp8266/example_125k_raw/rf_data_gen.c b/esp8266/example_125k_raw/rf_data_gen.c new file mode 100644 index 0000000..c2d52e2 --- /dev/null +++ b/esp8266/example_125k_raw/rf_data_gen.c @@ -0,0 +1,65 @@ +/** + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 + +const double center_frequency = 904.5; +const double bw = .125; +const uint32_t memory_offset = 0x20000; +#define SF_NUMBER 9 +#define SF_SYMBOL_TIME 0.000001 +#define MEM_MAX_BYTES 68000 + +#if SF_NUMBER < 7 +#warning SF6 still does not work :( +#endif + +#define SPI_DIV 1 + +// Funny modes: +/// 80MHz, SF8, SPI_DIV 5 @903.9/904.1 produces hilarious mirror images around 904.0 + +#if MAIN_MHZ == 80 +const double sample_rate = 1040.0/13.0/SPI_DIV; + +#elif MAIN_MHZ == 115 +const double sample_rate = 1040.0/9.0/SPI_DIV; + +#elif MAIN_MHZ == 52 +const double sample_rate = 1040.0/20.0/SPI_DIV; + +#elif MAIN_MHZ == 173 +const double sample_rate = 1040.0/6.0/SPI_DIV; + +#else +#error Unknown Clock Rate +#endif + + +#include "../../lib/rf_data_gen.h" + +int main() +{ + return gen_buffer_files(); +} diff --git a/esp8266/example_500k_raw/Makefile b/esp8266/example_500k_raw/Makefile new file mode 100644 index 0000000..5ee4da3 --- /dev/null +++ b/esp8266/example_500k_raw/Makefile @@ -0,0 +1,31 @@ +all : chirpbuff.dat.flash + +SUBMODULE=YES +SRCPREFIX=../nosdk8266/ +MAIN_MHZ=80 +SRCS=main.c +DEPS=chirpbuffinfo.h +COMPILECOUNT=$(shell cat compilecount.txt || true) +BUILDCOUNTCMD=echo 1+0$(COMPILECOUNT) | bc > compilecount.txt | true Compiled $(COMPILECOUNT) times +CFLAGS=-I../../lib -I.. + +include ../nosdk8266/Makefile + +rf_data_gen : rf_data_gen.c + gcc -o $@ $^ -lm -DMAIN_MHZ=$(MAIN_MHZ) + +chirpbuffinfo.h : chirpbuff.dat + +teststrap : main.c chirpbuff.dat + gcc -o teststrap main.c -DTESTSTRAP -I../nosdk8266/include + + +chirpbuff.dat : rf_data_gen + ./rf_data_gen + +chirpbuff.dat.flash : chirpbuff.dat + $(ESPUTIL) -b 115200 flash 0x20000 chirpbuff.dat + +cleanall : clean + rm -rf chirpbuff.h rf_data_gen chirpbuff.dat chirpbuffinfo.h + diff --git a/esp8266/example_500k_raw/README.md b/esp8266/example_500k_raw/README.md new file mode 100644 index 0000000..a407037 --- /dev/null +++ b/esp8266/example_500k_raw/README.md @@ -0,0 +1,5 @@ +# ESP8266 / ESP8285 Lora Transmitter + +Connect a small length of wire to the "RX" pin on your ESP8266, then it will transmit SF10 LoRa messages at 904.6MHz, with channel width of 500kHz. + +Be sure to configure your receiver to specifically use SF10, 500kHz, on 904.6MHz. Many commercial receivers cannot automatically negotiate 500kHz channels. diff --git a/esp8266/example_500k_raw/compilecount.txt b/esp8266/example_500k_raw/compilecount.txt new file mode 100644 index 0000000..9e5feb5 --- /dev/null +++ b/esp8266/example_500k_raw/compilecount.txt @@ -0,0 +1 @@ +46 diff --git a/esp8266/example_500k_raw/main.c b/esp8266/example_500k_raw/main.c new file mode 100644 index 0000000..2ab2ebb --- /dev/null +++ b/esp8266/example_500k_raw/main.c @@ -0,0 +1,294 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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 "esp8266_auxrom.h" +#include "eagle_soc.h" +#include "nosdk8266.h" +#include "esp8266_rom.h" + +// TODO: Use float number (related to 8) to fix the drift +#define call_delay_us(time) { asm volatile("mov.n a2, %0\n_call0 delay4clk" : : "r"(time * (MAIN_MHZ / 8)) : "a2" ); } + +#include "ets_sys.h" +#include "pin_mux_register.h" +#include "slc_register.h" +#include "dmastuff.h" +#include "chirpbuffinfo.h" +#include "LoRa-SDR-Code.h" + +#define DMABUFFERDEPTH 3 +//These contol the speed at which the bus comms. +#define WS_I2S_BCK SPI_DIV //Can't be less than 1. +#define WS_I2S_DIV 1 + +#ifndef TESTSTRAP +#include "esp8266_i2s_setup.h" +#endif + +uint32_t chirpbuffUP[CHIRPLENGTH_WORDS_WITH_PADDING]; +uint32_t chirpbuffDOWN[CHIRPLENGTH_WORDS_WITH_PADDING]; +uint32_t dummy[DMA_SIZE_WORDS]; + +volatile int fxcycle; +int etx; + +// This "should" be big enough to store up to 255 bytes of payload in a LoRa message. +#define MAX_SYMBOLS 532 + + +// Our table is bespoke for the specific SF. +#define CHIPSSPREAD CHIRPLENGTH_WORDS// QUARTER_CHIRP_LENGTH_WORDS (TODO: Use the quater value elsewhere in the code) +#define MARK_FROM_SF0 (1< We should check to make sure we are SLC_RX_EOF_INT_ST, but we are only getting one interrupt. + + WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff); + finishedDesc=(struct sdio_queue*)READ_PERI_REG(SLC_RX_EOF_DES_ADDR); + + etx++; + + if( quadsetplace < 0 ) + { + goto dump0; + } + + // LoRa symbols are in quarters of a chirp. + if( fxcycle>= NUM_DMAS_PER_QUARTER_CHIRP ) + { + fxcycle = 0; + quadsetplace++; + if( quadsetplace >= quadsetcount ) goto dump0; + } + + int symbol = quadsets[quadsetplace]; + + // Select down- or up-chirp. + if( symbol < 0 ) + { + int word = fxcycle * DMA_SIZE_WORDS - symbol - 1; + if( word >= CHIPSSPREAD ) word -= CHIPSSPREAD; + word++; + sendbuff = (chirpbuffDOWN + word); + } + else + { + int word = fxcycle * DMA_SIZE_WORDS + symbol; + if( word >= CHIPSSPREAD ) word -= CHIPSSPREAD; + sendbuff = (chirpbuffUP + word); + } + +#ifndef FOUND_PERFECT_DIVISOR + // Sometimes we do the full length, of all of the needed DMAs + // Sometimes we overshoot the time window, so we peel off 4 bytes. + // + // Very few combinations of clock rate, divisor, etc can produce + // perfect divisors. Most notably 52MHz, /2 SF9 can produce a perfect + // divisor. While this is very tidy and beautiful that the + // words would align perfectly, the actual difference it makes on + // LoRa's ability to receive the message is minimal. + // + // Additionally, 80MHz /2 SF7 can produce a perfect divisor. + int running_bits_after = runningcount_bits + DMA_SIZE_WORDS*32; + int overflow = running_bits_after - IDEAL_QUARTER_CHIRP_LENGTH_BITS; + if( overflow >= 0 ) + { + int overflow_amount = overflow / 32; + int overflow_remainder = overflow % 32; + sendlen = DMA_SIZE_WORDS*4 - 4*overflow_amount; + runningcount_bits = overflow_remainder; + + // XXX TODO: Why can't I put the logic for advancing the group in here? + } + else + { + sendlen = DMA_SIZE_WORDS*4; + runningcount_bits = running_bits_after; + } +#else + sendlen = DMA_SIZE_WORDS*4; +#endif + + finishedDesc->buf_ptr = (uint32_t)sendbuff; + finishedDesc->datalen = sendlen; + + fxcycle++; + return; + + +dump0: + // This location just always reads as zeroes. + finishedDesc->buf_ptr = (uint32_t)dummy; + quadsetplace = -1; + return; +} + +int main() +{ + // We store the bit pattern at flash:0x20000, so we don't have to constantly + // re-write it when working on code. + SPIRead( MEMORY_START_OFFSET_BYTES, chirpbuffUP, sizeof( chirpbuffUP ) ); + SPIRead( REVERSE_START_OFFSET_BYTES, chirpbuffDOWN, sizeof( chirpbuffDOWN ) ); + memset( dummy, 0, sizeof( dummy ) ); + + // Don't crank up clock speed til we're done with flash. + nosdk8266_init(); + + + int i = 0; + fxcycle = 0; + etx = 0; + + testi2s_init( dummy ); + + int frame = 0; + uint16_t lora_symbols[MAX_SYMBOLS]; + int lora_symbols_count; + + while(1) { + //12x this speed. + frame++; + + PIN_OUT_SET = _BV(2); //Turn GPIO2 light off. + //call_delay_us(1000000); + printf("ETX: %d %08x\n", fxcycle, chirpbuffUP[10] ); + PIN_OUT_CLEAR = _BV(2); //Turn GPIO2 light on. + call_delay_us(1000000); + + // Just some random data. + uint8_t payload_in[259] = { 0xbb, 0xcc, 0xde, 0x55, 0x22,}; + int payload_in_size = 6; + + static int msgno = 0; + payload_in[4] = msgno++; + + lora_symbols_count = 0; + int r = CreateMessageFromPayload( lora_symbols, &lora_symbols_count, MAX_SYMBOLS, SF_NUMBER, 4, payload_in, payload_in_size ); + + if( r < 0 ) + { + printf( "Failed to generate message (%d)\n", r ); + // Failed + continue; + } + + int j; + + quadsetcount = 0; + int32_t * qso = quadsets; + for( j = 0; j < PREAMBLE_CHIRPS; j++ ) + { + qso = AddChirp( qso, 0, 0 ); + } + + uint8_t syncword = 0x43; + #define CODEWORD_SHIFT 3 + + if( CODEWORD_LENGTH > 0 ) + qso = AddChirp( qso, ( ( syncword & 0xf ) << CODEWORD_SHIFT ), 0 ); + if( CODEWORD_LENGTH > 1 ) + qso = AddChirp( qso, ( ( ( syncword & 0xf0 ) >> 4 ) << CODEWORD_SHIFT ), 0); + + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + + if( SF_NUMBER <= 6 ) + { + // Two additional upchirps with SF6 https://github.com/tapparelj/gr-lora_sdr/issues/74#issuecomment-1891569580 + for( j = 0; j < 2; j++ ) + qso = AddChirp( qso, 0, 0 ); + } + + for( j = 0; j < lora_symbols_count; j++ ) + { + int ofs = lora_symbols[j]; + qso = AddChirp( qso, ofs, 0 ); + printf( "%02x ", ofs ); + } + printf( "\n" ); + + runningcount_bits = 0; + + // This tells the interrupt we have data. + quadsetcount = qso - quadsets + 0; + printf( "--- %d [%d] %d\n", lora_symbols_count, quadsetcount, CHIPSSPREAD/4 ); + quadsetplace = 0; + } + +} + diff --git a/esp8266/example_500k_raw/rf_data_gen.c b/esp8266/example_500k_raw/rf_data_gen.c new file mode 100644 index 0000000..8490b16 --- /dev/null +++ b/esp8266/example_500k_raw/rf_data_gen.c @@ -0,0 +1,65 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 + +const double center_frequency = 904.6; +const double bw = .5; +const uint32_t memory_offset = 0x20000; +#define SF_NUMBER 10 +#define SF_SYMBOL_TIME 0.00000025 +#define MEM_MAX_BYTES 68000 + +#if SF_NUMBER < 7 +#warning SF6 still does not work :( +#endif + +#define SPI_DIV 1 + +// Funny modes: +/// 80MHz, SF8, SPI_DIV 5 @903.9/904.1 produces hilarious mirror images around 904.0 + +#if MAIN_MHZ == 80 +const double sample_rate = 1040.0/13.0/SPI_DIV; + +#elif MAIN_MHZ == 115 +const double sample_rate = 1040.0/9.0/SPI_DIV; + +#elif MAIN_MHZ == 52 +const double sample_rate = 1040.0/20.0/SPI_DIV; + +#elif MAIN_MHZ == 173 +const double sample_rate = 1040.0/6.0/SPI_DIV; + +#else +#error Unknown Clock Rate +#endif + + +#include "../../lib/rf_data_gen.h" + +int main() +{ + return gen_buffer_files(); +} diff --git a/esp8266/lorawan_example/Makefile b/esp8266/lorawan_example/Makefile new file mode 100644 index 0000000..b77b2b8 --- /dev/null +++ b/esp8266/lorawan_example/Makefile @@ -0,0 +1,31 @@ +all : chirpbuff.dat.flash + +SUBMODULE=YES +SRCPREFIX=../nosdk8266/ +MAIN_MHZ=173 +SRCS=main.c +DEPS=chirpbuffinfo.h +COMPILECOUNT=$(shell cat compilecount.txt || true) +BUILDCOUNTCMD=echo 1+0$(COMPILECOUNT) | bc > compilecount.txt | true Compiled $(COMPILECOUNT) times +CFLAGS=-I../../lib -I.. + +include ../nosdk8266/Makefile + +rf_data_gen : rf_data_gen.c + gcc -o $@ $^ -lm -DMAIN_MHZ=$(MAIN_MHZ) + +chirpbuffinfo.h : chirpbuff.dat + +teststrap : main.c chirpbuff.dat + gcc -o teststrap main.c -DTESTSTRAP -I../nosdk8266/include + + +chirpbuff.dat : rf_data_gen + ./rf_data_gen + +chirpbuff.dat.flash : chirpbuff.dat + $(ESPUTIL) -b 115200 flash 0x20000 chirpbuff.dat + +cleanall : clean + rm -rf chirpbuff.h rf_data_gen chirpbuff.dat chirpbuffinfo.h + diff --git a/esp8266/lorawan_example/README.md b/esp8266/lorawan_example/README.md new file mode 100644 index 0000000..e421135 --- /dev/null +++ b/esp8266/lorawan_example/README.md @@ -0,0 +1,27 @@ +# ESP8266 / ESP8285 TheThings Network LoRaWAN transmitter. + +Same as the others - connect a small length of wire to the "RX" pin on your ESP8266, then it will transmit SF7 LoRa messages at 904.1MHz. + +But this, has the code in main() to send frames to thethings.network as valid LoRaWAN frames. + + +On thethings.network, + +1. Generate a new app. +2. Register a new device. +3. Select `Enter end device specifics manually` +4. Select US Plan 902-928, FSB2 (Used by TTN) +5. LoRaWAN Specification 1.0.0 +6. TS001 Technical Specificaiton 1.0.0 +7. "Show Advanced activation, LoRaWAN class and cluster settings" +8. Activation by Personalization +9. No addtional LoRaWAN class capabilities (class A only) +10. Use Network's default MAC settings. +11. Generate new EUI. +12. Generate new Device ID. + +Add the device, it may make sense to back out to the menu so you can copy the LSB for the address, and the code for MSB for keys. + +Replace the `payload_key`, `network_skey`, and `devaddress` in `main.c` + + diff --git a/esp8266/lorawan_example/compilecount.txt b/esp8266/lorawan_example/compilecount.txt new file mode 100644 index 0000000..5bc6609 --- /dev/null +++ b/esp8266/lorawan_example/compilecount.txt @@ -0,0 +1 @@ +117 diff --git a/esp8266/lorawan_example/main.c b/esp8266/lorawan_example/main.c new file mode 100644 index 0000000..380086e --- /dev/null +++ b/esp8266/lorawan_example/main.c @@ -0,0 +1,333 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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. + +**/ + +// Transmit LoRaWAN Packets from an ESP8266 - be sure to fill in your +// payload_key, network_skey and devaddress + +#include "esp8266_auxrom.h" +#include "eagle_soc.h" +#include "nosdk8266.h" +#include "esp8266_rom.h" +#include "ets_sys.h" +#include "pin_mux_register.h" +#include "chirpbuffinfo.h" +#include "LoRa-SDR-Code.h" + + +#define DMABUFFERDEPTH 3 +//These contol the speed at which the bus comms. +#define WS_I2S_BCK SPI_DIV //Can't be less than 1. +#define WS_I2S_DIV 1 + +#include "esp8266_i2s_setup.h" + +#include "lorawan_simple.h" + + +uint32_t chirpbuffUP[CHIRPLENGTH_WORDS_WITH_PADDING]; +uint32_t chirpbuffDOWN[CHIRPLENGTH_WORDS_WITH_PADDING]; +uint32_t dummy[DMA_SIZE_WORDS]; + +volatile int fxcycle; +int etx; + +// Practical limit because of RAM usage. But this should be able to hold a full-sized (255-byte) LoRa packet. +#define MAX_SYMBOLS 532 + + +// Our table is bespoke for the specific SF. +#define CHIPSSPREAD CHIRPLENGTH_WORDS// QUARTER_CHIRP_LENGTH_WORDS (TODO: Use the quater value elsewhere in the code) +#define MARK_FROM_SF0 (1<= NUM_DMAS_PER_QUARTER_CHIRP ) + { + fxcycle = 0; + quadsetplace++; + if( quadsetplace >= quadsetcount ) goto dump0; + } + + int symbol = quadsets[quadsetplace]; + + // Select down- or up-chirp. + if( symbol < 0 ) + { + int word = fxcycle * DMA_SIZE_WORDS - symbol - 1; + if( word >= CHIPSSPREAD ) word -= CHIPSSPREAD; + word++; + sendbuff = (chirpbuffDOWN + word); + } + else + { + int word = fxcycle * DMA_SIZE_WORDS + symbol; + if( word >= CHIPSSPREAD ) word -= CHIPSSPREAD; + sendbuff = (chirpbuffUP + word); + } + +#ifndef FOUND_PERFECT_DIVISOR + // Sometimes we do the full length, of all of the needed DMAs + // Sometimes we overshoot the time window, so we peel off 4 bytes. + // + // Very few combinations of clock rate, divisor, etc can produce + // perfect divisors. Most notably 52MHz, /2 SF9 can produce a perfect + // divisor. While this is very tidy and beautiful that the + // words would align perfectly, the actual difference it makes on + // LoRa's ability to receive the message is minimal. + // + // Additionally, 80MHz /2 SF7 can produce a perfect divisor. + int running_bits_after = runningcount_bits + DMA_SIZE_WORDS*32; + int overflow = running_bits_after - IDEAL_QUARTER_CHIRP_LENGTH_BITS; + if( overflow >= 0 ) + { + int overflow_amount = overflow / 32; + int overflow_remainder = overflow % 32; + sendlen = DMA_SIZE_WORDS*4 - 4*overflow_amount; + runningcount_bits = overflow_remainder; + + // XXX TODO: Why can't I put the logic for advancing the group in here? + } + else + { + sendlen = DMA_SIZE_WORDS*4; + runningcount_bits = running_bits_after; + } +#else + sendlen = DMA_SIZE_WORDS*4; +#endif + + finishedDesc->buf_ptr = (uint32_t)sendbuff; + finishedDesc->datalen = sendlen; + + fxcycle++; + return; + + +dump0: + // This location just always reads as zeroes. + finishedDesc->buf_ptr = (uint32_t)dummy; + quadsetplace = -1; + return; +} + +int main() +{ + // We store the bit pattern at flash:0x20000, so we don't have to constantly + // re-write it when working on code. + SPIRead( MEMORY_START_OFFSET_BYTES, chirpbuffUP, sizeof( chirpbuffUP ) ); + SPIRead( REVERSE_START_OFFSET_BYTES, chirpbuffDOWN, sizeof( chirpbuffDOWN ) ); + memset( dummy, 0, sizeof( dummy ) ); + + // Don't crank up clock speed til we're done with flash. + nosdk8266_init(); + + + int i = 0; + fxcycle = 0; + etx = 0; + // Configure GPIO5 (TX) and GPIO2 (LED) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5); + PIN_DIR_OUTPUT = _BV(2); //Enable GPIO2 light off. + + // Run the I2S bus at 1040/6 = 173.333 MHz. + // It looks like, at least on my part, if I try running + // hotter it can get to 1040/5.1 but not all the way to + // 5 so it's unstable there. + + testi2s_init( dummy ); + + int frame = 0; + uint16_t lora_symbols[MAX_SYMBOLS]; + int lora_symbols_count; + + frame = 0; + + while(1) { + //12x this speed. + frame++; + + PIN_OUT_SET = _BV(2); //Turn GPIO2 light off. + printf("ETX: %d %08x\n", fxcycle, chirpbuffUP[10] ); + PIN_OUT_CLEAR = _BV(2); //Turn GPIO2 light on. + call_delay_us(5000000); + + // Send a message with LoraWan. Formatted specifically for thethings.network. + uint8_t inner_payload_raw[20] = { 'T', 'e', 's', 't', '0', '0', '0', '0', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; + inner_payload_raw[4] = ((frame/1000)%10)+'0'; + inner_payload_raw[5] = ((frame/100)%10)+'0'; + inner_payload_raw[6] = ((frame/10)%10)+'0'; + inner_payload_raw[7] = (frame%10)+'0'; + int inner_payload_len = 20; + + // Get these from your thethings.network console. + // GENERAL NOTE: When addinga new device, go to General Settings -> Network Layer -> Advanced MAC Settings -> Resets frame counters [check] + static const uint8_t payload_key[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // AppSKey Big Endian + static const uint8_t network_skey[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // NwkSKey Big Endian + static const uint8_t devaddress[4] = { 0x00, 0x00, 0x00, 0x00 }; // Device address Little Endian LSB (Written backwards from Device address default view) +#warning Please set payload_key, network_skey and devaddress + + // Just some random data. + uint8_t raw_payload_with_b0[259+8] = { }; + uint8_t * raw_payload = raw_payload_with_b0 + 16; + uint8_t * pl = raw_payload; + int raw_payload_size = 0; + + pl += GenerateLoRaWANPacket( raw_payload_with_b0, inner_payload_raw, inner_payload_len, payload_key, network_skey, devaddress, frame); + + raw_payload_size = pl - raw_payload; + + printf( "Length: %d\n", raw_payload_size ); + + for( i = 0; i < raw_payload_size; i++ ) + printf( "%02x ", raw_payload[i] ); + + printf( "\n" ); + + lora_symbols_count = 0; + int r = CreateMessageFromPayload( lora_symbols, &lora_symbols_count, MAX_SYMBOLS, SF_NUMBER, 4, raw_payload, raw_payload_size ); + + if( r < 0 ) + { + printf( "Failed to generate message (%d)\n", r ); + // Failed + continue; + } + + int j; + + quadsetcount = 0; + int32_t * qso = quadsets; + for( j = 0; j < PREAMBLE_CHIRPS; j++ ) + { + qso = AddChirp( qso, 0, 0 ); + } + + uint8_t syncword = 0x43; + + #define CODEWORD_SHIFT 3 + + if( CODEWORD_LENGTH > 0 ) + qso = AddChirp( qso, ( ( syncword & 0xf ) << CODEWORD_SHIFT ), 0 ); + if( CODEWORD_LENGTH > 1 ) + qso = AddChirp( qso, ( ( ( syncword & 0xf0 ) >> 4 ) << CODEWORD_SHIFT ), 0); + + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 1 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 2 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 3 / 4 )-1; + *(qso++) = -(CHIPSSPREAD * 0 / 4 )-1; + + if( SF_NUMBER <= 6 ) + { + // Two additional upchirps with SF6 https://github.com/tapparelj/gr-lora_sdr/issues/74#issuecomment-1891569580 + for( j = 0; j < 2; j++ ) + qso = AddChirp( qso, 0, 0 ); + } + + for( j = 0; j < lora_symbols_count; j++ ) + { + int ofs = lora_symbols[j]; + //ofs = ofs ^ ((MARK_FROM_SF6<<6) -1); + //ofs &= (MARK_FROM_SF6<<6) -1; + qso = AddChirp( qso, ofs, 0 ); + printf( "%02x ", ofs ); + } + printf( "\n" ); + + runningcount_bits = 0; + + // This tells the interrupt we have data. + quadsetcount = qso - quadsets + 0; + printf( "--- %d [%d] %d frame %08x\n", lora_symbols_count, quadsetcount, CHIPSSPREAD/4, frame ); + quadsetplace = 0; + } + +} + diff --git a/esp8266/lorawan_example/reference.txt b/esp8266/lorawan_example/reference.txt new file mode 100644 index 0000000..e741334 --- /dev/null +++ b/esp8266/lorawan_example/reference.txt @@ -0,0 +1,189 @@ + Known Reference + QF/ZDCaAGwAB1Rwa9Hh7AF9mVtq3 -> (CRC 41445, SF10 CR 4/5, 904.5MHz) -> App Payload 1Rwa9Hh7AF8= -> Mikrotik address 26 0C D9 5F -> + From the things network: QF/ZDCaAGwAB1Rwa9Hh7AF9mVtq3 "frm_payload": "1Rwa9Hh7AF8=" // "mic": "Zlbatw==", + +// 8 A's. 0x41 x 8 + +// Full raw packet +405fd90c26801b0001 + d51c1af4787b005f + 6656dab7 + +// My test +405fd90c26801b0001 + d51c1af4787b005f + 6656dab7 + +{ + "name": "as.up.data.forward", + "time": "2024-02-18T03:25:33.806043236Z", + "identifiers": [ + { + "device_ids": { + "device_id": "eui-70b3d57ed00651da", + "application_ids": { + "application_id": "cursed-esp8266" + }, + "dev_eui": "70B3D57ED00651DA", + "dev_addr": "260CD95F" + } + } + ], + "data": { + "@type": "type.googleapis.com/ttn.lorawan.v3.ApplicationUp", + "end_device_ids": { + "device_id": "eui-70b3d57ed00651da", + "application_ids": { + "application_id": "cursed-esp8266" + }, + "dev_eui": "70B3D57ED00651DA", + "dev_addr": "260CD95F" + }, + "correlation_ids": [ + "gs:uplink:01HPX3YSGKBGH71N3Q8T2BGJCM" + ], + "received_at": "2024-02-18T03:25:33.803070864Z", + "uplink_message": { + "f_port": 1, + "f_cnt": 27, + "frm_payload": "QUFBQUFBQUE=", + "rx_metadata": [ + { + "gateway_ids": { + "gateway_id": "eui-343632383e002300", + "eui": "343632383E002300" + }, + "time": "2024-02-18T03:25:25.274488Z", + "timestamp": 1948262652, + "rssi": -33, + "channel_rssi": -33, + "snr": 12.5, + "uplink_token": "CiIKIAoUZXVpLTM0MzYzMjM4M2UwMDIzMDASCDQ2Mjg+ACMAEPzBgKEHGgwIrfHFrgYQ+IemmAIg4LCD7Nk4", + "channel_index": 3, + "received_at": "2024-02-18T03:25:33.573997023Z" + } + ], + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 10, + "coding_rate": "4/5" + } + }, + "frequency": "904500000", + "timestamp": 1948262652, + "time": "2024-02-18T03:25:25.274488Z" + }, + "received_at": "2024-02-18T03:25:33.589092783Z", + "consumed_airtime": "0.370688s", + "network_ids": { + "net_id": "000013", + "ns_id": "EC656E0000000182", + "tenant_id": "ttn", + "cluster_id": "nam1", + "cluster_address": "nam1.cloud.thethings.network" + } + } + }, + "correlation_ids": [ + "gs:uplink:01HPX3YSGKBGH71N3Q8T2BGJCM" + ], + "origin": "ip-10-101-7-121.us-west-1.compute.internal", + "context": { + "tenant-id": "CgN0dG4=" + }, + "visibility": { + "rights": [ + "RIGHT_APPLICATION_TRAFFIC_READ" + ] + }, + "unique_id": "01HPX3YSQE3XHB4JGNEBQYAB2E" +} + + + + + +{ + "name": "gs.up.receive", + "time": "2024-02-18T03:25:33.588003627Z", + "identifiers": [ + { + "gateway_ids": { + "gateway_id": "eui-343632383e002300", + "eui": "343632383E002300" + } + } + ], + "data": { + "@type": "type.googleapis.com/ttn.lorawan.v3.GatewayUplinkMessage", + "message": { + "raw_payload": "QF/ZDCaAGwAB1Rwa9Hh7AF9mVtq3", + "payload": { + "m_hdr": { + "m_type": "UNCONFIRMED_UP" + }, + "mic": "Zlbatw==", + "mac_payload": { + "f_hdr": { + "dev_addr": "260CD95F", + "f_ctrl": { + "adr": true + }, + "f_cnt": 27 + }, + "f_port": 1, + "frm_payload": "1Rwa9Hh7AF8=" + } + }, + "settings": { + "data_rate": { + "lora": { + "bandwidth": 125000, + "spreading_factor": 10, + "coding_rate": "4/5" + } + }, + "frequency": "904500000", + "timestamp": 1948262652, + "time": "2024-02-18T03:25:25.274488Z" + }, + "rx_metadata": [ + { + "gateway_ids": { + "gateway_id": "eui-343632383e002300", + "eui": "343632383E002300" + }, + "time": "2024-02-18T03:25:25.274488Z", + "timestamp": 1948262652, + "rssi": -33, + "channel_rssi": -33, + "snr": 12.5, + "uplink_token": "CiIKIAoUZXVpLTM0MzYzMjM4M2UwMDIzMDASCDQ2Mjg+ACMAEPzBgKEHGgwIrfHFrgYQ+IemmAIg4LCD7Nk4", + "channel_index": 3, + "received_at": "2024-02-18T03:25:33.573997023Z" + } + ], + "received_at": "2024-02-18T03:25:33.587826168Z", + "correlation_ids": [ + "gs:uplink:01HPX3YSGKBGH71N3Q8T2BGJCM" + ], + "crc_status": true + }, + "band_id": "US_902_928" + }, + "correlation_ids": [ + "gs:uplink:01HPX3YSGKBGH71N3Q8T2BGJCM" + ], + "origin": "ip-10-101-4-161.us-west-1.compute.internal", + "context": { + "tenant-id": "CgN0dG4=" + }, + "visibility": { + "rights": [ + "RIGHT_GATEWAY_TRAFFIC_READ" + ] + }, + "unique_id": "01HPX3YSGMTSH0JBWT8BEZQJRC" +} diff --git a/esp8266/lorawan_example/rf_data_gen.c b/esp8266/lorawan_example/rf_data_gen.c new file mode 100644 index 0000000..ff92dc3 --- /dev/null +++ b/esp8266/lorawan_example/rf_data_gen.c @@ -0,0 +1,65 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 + +const double center_frequency = 904.1; +const double bw = .125; +const uint32_t memory_offset = 0x20000; +#define SF_NUMBER 7 +#define SF_SYMBOL_TIME 0.000001 +#define MEM_MAX_BYTES 68000 + +#if SF_NUMBER < 7 +#warning SF6 still does not work :( +#endif + +#define SPI_DIV 1 + +// Funny modes: +/// 80MHz, SF8, SPI_DIV 5 @903.9/904.1 produces hilarious mirror images around 904.0 + +#if MAIN_MHZ == 80 +const double sample_rate = 1040.0/13.0/SPI_DIV; + +#elif MAIN_MHZ == 115 +const double sample_rate = 1040.0/9.0/SPI_DIV; + +#elif MAIN_MHZ == 52 +const double sample_rate = 1040.0/20.0/SPI_DIV; + +#elif MAIN_MHZ == 173 +const double sample_rate = 1040.0/6.0/SPI_DIV; + +#else +#error Unknown Clock Rate +#endif + + +#include "../../lib/rf_data_gen.h" + +int main() +{ + return gen_buffer_files(); +} diff --git a/esp8266/non_lora_310_transmit/Makefile b/esp8266/non_lora_310_transmit/Makefile new file mode 100644 index 0000000..fb994c1 --- /dev/null +++ b/esp8266/non_lora_310_transmit/Makefile @@ -0,0 +1,25 @@ +all : flash + +SUBMODULE=YES +SRCPREFIX=../nosdk8266/ +MAIN_MHZ=173 +SRCS=main.c +DEPS=samples.h +COMPILECOUNT=$(shell cat compilecount.txt || true) +BUILDCOUNTCMD=echo 1+0$(COMPILECOUNT) | bc > compilecount.txt | true Compiled $(COMPILECOUNT) times +CFLAGS=-I../../lib + +include ../nosdk8266/Makefile + +rf_data_gen : rf_data_gen.c + gcc -g -Og -o $@ $^ -lm -DMAIN_MHZ=$(MAIN_MHZ) + +samples.h : rf_data_gen + ./rf_data_gen + +#chirpbuff.dat.flash : chirpbuff.dat +# $(ESPUTIL) -b 115200 flash 0x20000 chirpbuff.dat + +cleanall : clean + rm -rf rf_data_gen samples.h + diff --git a/esp8266/non_lora_310_transmit/README.md b/esp8266/non_lora_310_transmit/README.md new file mode 100644 index 0000000..33c5d22 --- /dev/null +++ b/esp8266/non_lora_310_transmit/README.md @@ -0,0 +1,11 @@ +# ESP8266 / ESP8285 310 MHz Transmitter + +Transmits a 310 (or configurable) OOK pulse coded signal out the RX pin on the ESP8266/ESP8286. + +You can also test it with an SDR and define + +```c +#define CONTINUOUS_TONE +``` + +Frequency / word length can be configured in `rf_data_gen.c` diff --git a/esp8266/non_lora_310_transmit/compilecount.txt b/esp8266/non_lora_310_transmit/compilecount.txt new file mode 100644 index 0000000..5bc6609 --- /dev/null +++ b/esp8266/non_lora_310_transmit/compilecount.txt @@ -0,0 +1 @@ +117 diff --git a/esp8266/non_lora_310_transmit/main.c b/esp8266/non_lora_310_transmit/main.c new file mode 100644 index 0000000..c806938 --- /dev/null +++ b/esp8266/non_lora_310_transmit/main.c @@ -0,0 +1,294 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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 "esp8266_auxrom.h" +#include "eagle_soc.h" +#include "nosdk8266.h" +#include "esp8266_rom.h" +#include +#include "ets_sys.h" +#include "pin_mux_register.h" +#include "slc_register.h" +#include "dmastuff.h" +#include "samples.h" + +//#define CONTINUOUS_TONE + +// The speed at which bits are shifted out - this is done with trial and error. Try one speed +// and figure out how it aligns to your target system. The units are too messy for me to be +// troubled with thinking of. + +#define BIT_RATE 245 +#define num_replays (( SAMPLE_RATE / (DMA_WORDS*NUMBITS) ) / BIT_RATE) + +uint8_t output_buffer[] = { + // OOK, map to time_limits_for_bits, 0 is short pulse, 1 is long pulse, 2 is no-signal. + // You will need to manually use your 310MHz device and record the pulse timing + // To fill out this array with thecorrect code for your opener. + 0, 1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 1, 0, 1, 0, 1, 0, 0, 1, 1, +}; +uint32_t time_limits_for_bits[3] = { num_replays/8, num_replays/2, 0 }; +uint32_t dummy[DMA_WORDS]; + +void testi2s_init(); + +//These contol the speed at which the bus comms. +#define DMABUFFERDEPTH 3 +#define WS_I2S_BCK SPI_DIV //Can't be less than 1. +#define WS_I2S_DIV 1 +#define call_delay_us(time) { asm volatile("mov.n a2, %0\n_call0 delay4clk" : : "r"(time * (MAIN_MHZ / 8)) : "a2" ); } + +//I2S DMA buffer descriptors +static struct sdio_queue i2sBufDescTX[DMABUFFERDEPTH] __attribute__((aligned(128)));; + +volatile int output_buffer_place = 1000000; +volatile int count_out_this_bit = 0; +volatile int etx = 0; + +void slc_isr(void * v) { + + uint32_t * sendbuff = 0; + + struct sdio_queue *finishedDesc; +// slc_intr_status = READ_PERI_REG(SLC_INT_STATUS); -> We should check to make sure we are SLC_RX_EOF_INT_ST, but we are only getting one interrupt. + + WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff); + finishedDesc=(struct sdio_queue*)READ_PERI_REG(SLC_RX_EOF_DES_ADDR); + +#ifdef CONTINUOUS_TONE + return; +#endif + + etx++; + + if( output_buffer_place >= sizeof( output_buffer ) / sizeof( output_buffer[0] ) ) + { + goto dump0; + } + + count_out_this_bit++; + + if( count_out_this_bit >= num_replays ) + { + count_out_this_bit = 0; + output_buffer_place++; + + if( output_buffer_place >= sizeof( output_buffer ) / sizeof( output_buffer[0] ) ) + { + goto dump0; + } + } + + int symbol = output_buffer[output_buffer_place]; + + if( count_out_this_bit < time_limits_for_bits[symbol] ) + { + sendbuff = samples; + } + else + { + sendbuff = dummy; + } + + finishedDesc->buf_ptr = (uint32_t)sendbuff; + finishedDesc->datalen = DMA_WORDS*4; + + return; +dump0: + finishedDesc->buf_ptr = (uint32_t)dummy; + finishedDesc->datalen = DMA_WORDS*4; + return; +} + + +#ifdef TESTSTRAP + +void SPIRead( uint32_t pos, uint32_t * buff, int len ) +{ + memcpy( buff, (pos - 0x00020000) + (uint8_t*)chirpbuff, len ); +} + +void nosdk8266_init() +{ +} + + +void testi2s_init() +{ +} + +#else + +//Initialize I2S subsystem for DMA circular buffer use +void testi2s_init() { + int x, y; + //Bits are shifted out + + //Initialize DMA buffer descriptors in such a way that they will form a circular + //buffer. + + for (x=0; x +#include +#include + +const double rf_frequency = 310; +//const double spread = 0.000001; +const double spread = 0.0; + +#define SPI_DIV 1 + +#if MAIN_MHZ == 80 +const double sample_rate = 1040.0/13.0/SPI_DIV; + +#elif MAIN_MHZ == 115 +const double sample_rate = 1040.0/9.0/SPI_DIV; + +#elif MAIN_MHZ == 52 +const double sample_rate = 1040.0/20.0/SPI_DIV; + +#elif MAIN_MHZ == 173 +const double sample_rate = 1040.0/6.0/SPI_DIV; + +#else +#error Unknown Clock Rate +#endif + +#define MAX_WORDS_DMA 511 +#define NUMBITS 32 + +int main() +{ + int i; + FILE * fcba = fopen( "samples.h", "w" ); + double phase = 0; + uint32_t samplect = 0; + uint32_t words = 0; + uint32_t sample_word = 0; + int32_t best_words = -1; + double best_phase = 1000; + double current_frequency = rf_frequency; + for( i = 0; i < MAX_WORDS_DMA*NUMBITS; i++ ) + { + phase += 3.1415926 * 2 * current_frequency / sample_rate; + current_frequency += spread; + while( phase > 3.1415926 * 2.0 ) phase -= 3.1415926 * 2.0; + samplect++; + if( samplect == NUMBITS ) + { + words++; + printf( "Phase Delta at %d: %f\n", words, phase ); + if( words > 64 ) // Minimum number of words + { + double phasediff = ( phase > 3.1415926 ) ? (3.1415926*2.0 - phase) : phase; + if( phasediff < best_phase ) + { + best_phase = phasediff; + best_words = words; + } + } + samplect = 0; + } + } + + uint32_t num_words = best_words; + + printf( "Selected %d words\n", num_words ); + samplect = 0; + words = 0; + sample_word = 0; + phase = 0; + current_frequency = rf_frequency; + + fprintf( fcba, "uint32_t samples[%d] = { \n\t", num_words ); + for( i = 0; i < num_words*NUMBITS; i++ ) + { + phase += 3.1415926 * 2 * current_frequency / sample_rate; + while( phase > 3.1415926 * 2.0 ) phase -= 3.1415926 * 2.0; + current_frequency += spread; + + // This is the magic line - this is what decides if you are emitting a `1` bit or a `0` bit. + int bit = sin( phase ) > 0.0; // HINT: if you want to mix multiple signals, add a DC offset here. + sample_word |= !!bit; + samplect++; + if( samplect == NUMBITS ) + { +#ifdef USE_16_BITS + fprintf( fcba, "0x%04x,%s", sample_word, ((words & 0xf) != 0xf)?" ":"\n\t" ); +#else + fprintf( fcba, "0x%08x,%s", sample_word, ((words & 0xf) != 0xf)?" ":"\n\t" ); +#endif + //fwrite( &sample_word, 1, NUMBITS/8, fd ); + words++; + sample_word = 0; + samplect = 0; + } + sample_word <<= 1; + } + fprintf( fcba, "};\n" ); + fprintf( fcba, "#define DMA_WORDS %d\n", num_words ); + fprintf( fcba, "#define SPI_DIV %d\n", SPI_DIV ); + fprintf( fcba, "#define NUMBITS %d\n", NUMBITS ); + fprintf( fcba, "#define SAMPLE_RATE %d\n", (int)(sample_rate*1000000) ); +} + diff --git a/esp8266/nosdk8266 b/esp8266/nosdk8266 new file mode 160000 index 0000000..c1628f1 --- /dev/null +++ b/esp8266/nosdk8266 @@ -0,0 +1 @@ +Subproject commit c1628f15eee2f8f0ad8de9193a0b6c800b547d2e diff --git a/lib/LoRa-SDR-Code.h b/lib/LoRa-SDR-Code.h new file mode 100644 index 0000000..8c9192d --- /dev/null +++ b/lib/LoRa-SDR-Code.h @@ -0,0 +1,626 @@ +// NOTE: https://github.com/cnlohr/lorasoft/lib/LoRa-SDR-Code.h - IS UPSTREAM VERSION + +/* This code is lifted from LoRa-SDR. I found this copyright at the top + of one of their files: + +// Copyright (c) 2016-2016 Lime Microsystems +// Copyright (c) 2016-2016 Arne Hennig +// SPDX-License-Identifier: BSL-1.0 +// from https://github.com/myriadrf/LoRa-SDR/blob/master/LoRaEncoder.cpp + +Hopefully that covers some of the other stuff. + +For any portions of this file not covered under the above licensing terms, it +they shall be governed by the MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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. + +*/ + + +#ifndef _LORAENCODER_H +#define _LORAENCODER_H + + +// From LoRaCodes.hpp + +#include + +/*********************************************************************** + * Defines + **********************************************************************/ +#define HEADER_RDD 4 +#define N_HEADER_SYMBOLS (HEADER_RDD + 4) + + +/*********************************************************************** + * Round functions + **********************************************************************/ +static unsigned roundUp(unsigned num, unsigned factor) +{ + return ((num + factor - 1) / factor) * factor; +} + +/*********************************************************************** + * Simple 8-bit checksum routine + **********************************************************************/ +static uint8_t checksum8(const uint8_t *p, const size_t len) +{ + uint8_t acc = 0; + for (size_t i = 0; i < len; i++) + { + acc = (acc >> 1) + ((acc & 0x1) << 7); //rotate + acc += p[i]; //add + } + return acc; +} + +static uint8_t headerChecksum(const uint8_t *h) { + int a0 = (h[0] >> 4) & 0x1; + int a1 = (h[0] >> 5) & 0x1; + int a2 = (h[0] >> 6) & 0x1; + int a3 = (h[0] >> 7) & 0x1; + + int b0 = (h[0] >> 0) & 0x1; + int b1 = (h[0] >> 1) & 0x1; + int b2 = (h[0] >> 2) & 0x1; + int b3 = (h[0] >> 3) & 0x1; + + int c0 = (h[1] >> 0) & 0x1; + int c1 = (h[1] >> 1) & 0x1; + int c2 = (h[1] >> 2) & 0x1; + int c3 = (h[1] >> 3) & 0x1; + + uint8_t res; + res = (a0 ^ a1 ^ a2 ^ a3) << 4; + res |= (a3 ^ b1 ^ b2 ^ b3 ^ c0) << 3; + res |= (a2 ^ b0 ^ b3 ^ c1 ^ c3) << 2; + res |= (a1 ^ b0 ^ b2 ^ c0 ^ c1 ^ c2) << 1; + res |= a0 ^ b1 ^ c0 ^ c1 ^ c2 ^ c3; + + return res; +} + +static uint16_t crc16sx(uint16_t crc, const uint16_t poly) { + for (int i = 0; i < 8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ poly; + } + else { + crc <<= 1; + } + } + return crc; +} + +static uint8_t xsum8(uint8_t t) { + t ^= t >> 4; + t ^= t >> 2; + t ^= t >> 1; + return (t & 1); +} + +/*********************************************************************** + * CRC reverse engineered from Sx1272 data stream. + * Modified CCITT crc with masking of the output with an 8bit lfsr + **********************************************************************/ +static uint16_t sx1272DataChecksum(const uint8_t *data, int length) { + uint16_t res = 0; + uint8_t v = 0xff; + uint16_t crc = 0; + for (int i = 0; i < length; i++) { + crc = crc16sx(res, 0x1021); + v = xsum8(v & 0xB8) | (v << 1); + res = crc ^ data[i]; + } + res ^= v; + v = xsum8(v & 0xB8) | (v << 1); + res ^= v << 8; + return res; +} + + +/*********************************************************************** + * http://www.semtech.com/images/datasheet/AN1200.18_AG.pdf + **********************************************************************/ +static void SX1232RadioComputeWhitening( uint8_t *buffer, uint16_t bufferSize ) +{ + uint8_t WhiteningKeyMSB; // Global variable so the value is kept after starting the + uint8_t WhiteningKeyLSB; // de-whitening process + WhiteningKeyMSB = 0x01; // Init value for the LFSR, these values should be initialize only + WhiteningKeyLSB = 0xFF; // at the start of a whitening or a de-whitening process + // *buffer is a char pointer indicating the data to be whiten / de-whiten + // buffersize is the number of char to be whiten / de-whiten + // >> The whitened / de-whitened data are directly placed into the pointer + uint8_t i = 0; + uint16_t j = 0; + uint8_t WhiteningKeyMSBPrevious = 0; // 9th bit of the LFSR + for( j = 0; j < bufferSize; j++ ) // byte counter + { + buffer[j] ^= WhiteningKeyLSB; // XOR between the data and the whitening key + for( i = 0; i < 8; i++ ) // 8-bit shift between each byte + { + WhiteningKeyMSBPrevious = WhiteningKeyMSB; + WhiteningKeyMSB = ( WhiteningKeyLSB & 0x01 ) ^ ( ( WhiteningKeyLSB >> 5 ) & 0x01 ); + WhiteningKeyLSB= ( ( WhiteningKeyLSB >> 1 ) & 0xFF ) | ( ( WhiteningKeyMSBPrevious << 7 ) & 0x80 ); + } + } +} + + +/*********************************************************************** + * Whitening generator reverse engineered from Sx1272 data stream. + * Each bit of a codeword is combined with the output from a different position in the whitening sequence. + **********************************************************************/ +static void Sx1272ComputeWhitening(uint8_t *buffer, uint16_t bufferSize, const int bitOfs, const int RDD) { + static const int ofs0[8] = {6,4,2,0,-112,-114,-302,-34 }; // offset into sequence for each bit + static const int ofs1[5] = {6,4,2,0,-360 }; // different offsets used for single parity mode (1 == RDD) + static const int whiten_len = 510; // length of whitening sequence + static const uint64_t whiten_seq[8] = { // whitening sequence + 0x0102291EA751AAFFL,0xD24B050A8D643A17L,0x5B279B671120B8F4L,0x032B37B9F6FB55A2L, + 0x994E0F87E95E2D16L,0x7CBCFC7631984C26L,0x281C8E4F0DAEF7F9L,0x1741886EB7733B15L + }; + const int *ofs = (1 == RDD) ? ofs1 : ofs0; + int i, j; + for (j = 0; j < bufferSize; j++) { + uint8_t x = 0; + for (i = 0; i < 4 + RDD; i++) { + int t = (ofs[i] + j + bitOfs + whiten_len) % whiten_len; + if (whiten_seq[t >> 6] & ((uint64_t)1 << (t & 0x3F))) { + x |= 1 << i; + } + } + buffer[j] ^= x; + } +} + +/*********************************************************************** + * Whitening generator reverse engineered from Sx1272 data stream. + * Same as above but using the actual interleaved LFSRs. + **********************************************************************/ +static void Sx1272ComputeWhiteningLfsr(uint8_t *buffer, uint16_t bufferSize, const int bitOfs, const size_t RDD) { + static const uint64_t seed1[2] = {0x6572D100E85C2EFF,0xE85C2EFFFFFFFFFF}; // lfsr start values + static const uint64_t seed2[2] = {0x05121100F8ECFEEF,0xF8ECFEEFEFEFEFEF}; // lfsr start values for single parity mode (1 == RDD) + const uint8_t m = 0xff >> (4 - RDD); + uint64_t r[2] = {(1 == RDD)?seed2[0]:seed1[0],(1 == RDD)?seed2[1]:seed1[1]}; + int i,j; + for (i = 0; i < bitOfs;i++){ + r[i & 1] = (r[i & 1] >> 8) | (((r[i & 1] >> 32) ^ (r[i & 1] >> 24) ^ (r[i & 1] >> 16) ^ r[i & 1]) << 56); // poly: 0x1D + } + for (j = 0; j < bufferSize; j++,i++) { + buffer[j] ^= r[i & 1] & m; + r[i & 1] = (r[i & 1] >> 8) | (((r[i & 1] >> 32) ^ (r[i & 1] >> 24) ^ (r[i & 1] >> 16) ^ r[i & 1]) << 56); + } +} + +/*********************************************************************** + * https://en.wikipedia.org/wiki/Gray_code + **********************************************************************/ + +/* + * This function converts an unsigned binary + * number to reflected binary Gray code. + * + * The operator >> is shift right. The operator ^ is exclusive or. + */ +static unsigned short binaryToGray16(unsigned short num) +{ + return num ^ (num >> 1); +} + +/* + * A more efficient version, for Gray codes of 16 or fewer bits. + */ +static unsigned short grayToBinary16(unsigned short num) +{ + num = num ^ (num >> 8); + num = num ^ (num >> 4); + num = num ^ (num >> 2); + num = num ^ (num >> 1); + return num; +} + +/*********************************************************************** + * Encode a 4 bit word into a 8 bits with parity + * Non standard version used in sx1272. + * https://en.wikipedia.org/wiki/Hamming_code + **********************************************************************/ +static unsigned char encodeHamming84sx(const unsigned char x) +{ + int d0 = (x >> 0) & 0x1; + int d1 = (x >> 1) & 0x1; + int d2 = (x >> 2) & 0x1; + int d3 = (x >> 3) & 0x1; + + int b = x & 0xf; + b |= (d0 ^ d1 ^ d2) << 4; + b |= (d1 ^ d2 ^ d3) << 5; + b |= (d0 ^ d1 ^ d3) << 6; + b |= (d0 ^ d2 ^ d3) << 7; + return b; +} + +/*********************************************************************** + * Decode 8 bits into a 4 bit word with single bit correction. + * Non standard version used in sx1272. + * Set error to true when a parity error was detected + * Set bad to true when the result could not be corrected + **********************************************************************/ +static unsigned char decodeHamming84sx(const unsigned char b, int * error, int * bad) +{ + int b0 = (b >> 0) & 0x1; + int b1 = (b >> 1) & 0x1; + int b2 = (b >> 2) & 0x1; + int b3 = (b >> 3) & 0x1; + int b4 = (b >> 4) & 0x1; + int b5 = (b >> 5) & 0x1; + int b6 = (b >> 6) & 0x1; + int b7 = (b >> 7) & 0x1; + + int p0 = (b0 ^ b1 ^ b2 ^ b4); + int p1 = (b1 ^ b2 ^ b3 ^ b5); + int p2 = (b0 ^ b1 ^ b3 ^ b6); + int p3 = (b0 ^ b2 ^ b3 ^ b7); + + int parity = (p0 << 0) | (p1 << 1) | (p2 << 2) | (p3 << 3); + if (parity != 0) *error = 1; + switch (parity & 0xf) + { + case 0xD: return (b ^ 1) & 0xf; + case 0x7: return (b ^ 2) & 0xf; + case 0xB: return (b ^ 4) & 0xf; + case 0xE: return (b ^ 8) & 0xf; + case 0x0: + case 0x1: + case 0x2: + case 0x4: + case 0x8: return b & 0xf; + default: *bad = 1; return b & 0xf; + } +} + +/*********************************************************************** + * Encode a 4 bit word into a 7 bits with parity. + * Non standard version used in sx1272. + **********************************************************************/ +static unsigned char encodeHamming74sx(const unsigned char x) +{ + int d0 = (x >> 0) & 0x1; + int d1 = (x >> 1) & 0x1; + int d2 = (x >> 2) & 0x1; + int d3 = (x >> 3) & 0x1; + + unsigned char b = x & 0xf; + b |= (d0 ^ d1 ^ d2) << 4; + b |= (d1 ^ d2 ^ d3) << 5; + b |= (d0 ^ d1 ^ d3) << 6; + return b; +} + +/*********************************************************************** + * Decode 7 bits into a 4 bit word with single bit correction. + * Non standard version used in sx1272. + * Set error to true when a parity error was detected + **********************************************************************/ +static unsigned char decodeHamming74sx(const unsigned char b, int * error) +{ + int b0 = (b >> 0) & 0x1; + int b1 = (b >> 1) & 0x1; + int b2 = (b >> 2) & 0x1; + int b3 = (b >> 3) & 0x1; + int b4 = (b >> 4) & 0x1; + int b5 = (b >> 5) & 0x1; + int b6 = (b >> 6) & 0x1; + + int p0 = (b0 ^ b1 ^ b2 ^ b4); + int p1 = (b1 ^ b2 ^ b3 ^ b5); + int p2 = (b0 ^ b1 ^ b3 ^ b6); + + int parity = (p0 << 0) | (p1 << 1) | (p2 << 2); + if (parity != 0) *error = 1; + switch (parity) + { + case 0x5: return (b ^ 1) & 0xf; + case 0x7: return (b ^ 2) & 0xf; + case 0x3: return (b ^ 4) & 0xf; + case 0x6: return (b ^ 8) & 0xf; + case 0x0: + case 0x1: + case 0x2: + case 0x4: return b & 0xF; + } + return b & 0xf; +} + +/*********************************************************************** + * Check parity for 5/4 code. + * return true if parity is valid. + **********************************************************************/ +static unsigned char checkParity54(const unsigned char b, int *error) { + int x = b ^ (b >> 2); + x = x ^ (x >> 1) ^ (b >> 4); + if (x & 1) *error = 1; + return b & 0xf; +} + +static unsigned char encodeParity54(const unsigned char b) { + int x = b ^ (b >> 2); + x = x ^ (x >> 1); + return (b & 0xf) | ((x << 4) & 0x10); +} + +/*********************************************************************** +* Check parity for 6/4 code. +* return true if parity is valid. +**********************************************************************/ +static unsigned char checkParity64(const unsigned char b, int *error) { + int x = b ^ (b >> 1) ^ (b >> 2); + int y = x ^ b ^ (b >> 3); + + x ^= b >> 4; + y ^= b >> 5; + if ((x | y) & 1) *error = 1; + return b & 0xf; +} + +static unsigned char encodeParity64(const unsigned char b) { + int x = b ^ (b >> 1) ^ (b >> 2); + int y = x ^ b ^ (b >> 3); + return ((x & 1) << 4) | ((y & 1) << 5) | (b & 0xf); +} + +/*********************************************************************** + * Diagonal interleaver + deinterleaver + **********************************************************************/ +static void diagonalInterleaveSx(const uint8_t *codewords, const size_t numCodewords, uint16_t *symbols, const size_t PPM, const size_t RDD){ + for (size_t x = 0; x < numCodewords / PPM; x++) { + const size_t cwOff = x*PPM; + const size_t symOff = x*(4 + RDD); + for (size_t k = 0; k < 4 + RDD; k++){ + uint16_t s = symbols[symOff + k]; + for (size_t m = 0; m < PPM; m++){ + const size_t i = (m + k + PPM) % PPM; + const int bit = (codewords[cwOff + i] >> k) & 0x1; + s |= (bit << m); + } + symbols[symOff + k] = s; + } + } +} + +static void diagonalDeterleaveSx(const uint16_t *symbols, const size_t numSymbols, uint8_t *codewords, const size_t PPM, const size_t RDD) +{ + for (size_t x = 0; x < numSymbols / (4 + RDD); x++) + { + const size_t cwOff = x*PPM; + const size_t symOff = x*(4 + RDD); + for (size_t k = 0; k < 4 + RDD; k++) + { + for (size_t m = 0; m < PPM; m++) + { + const size_t i = (m + k) % PPM; + const int bit = (symbols[symOff + k] >> m) & 0x1; + codewords[cwOff + i] |= (bit << k); + } + } + } +} + +static void diagonalDeterleaveSx2(const uint16_t *symbols, const size_t numSymbols, uint8_t *codewords, const size_t PPM, const size_t RDD) +{ + size_t nb = RDD + 4; + for (size_t x = 0; x < numSymbols / nb; x++) { + const size_t cwOff = x*PPM; + const size_t symOff = x*nb; + for (size_t m = 0; m < PPM; m++) { + size_t i = m; + int sym = symbols[symOff + m]; + for (size_t k = 0; k < PPM; k++, sym >>= 1) { + codewords[cwOff + i] |= (sym & 1) << m; + if (++i == PPM) i = 0; + } + } + } +} + + + +static void encodeFec(uint8_t * codewords, const size_t RDD, size_t * cOfs, size_t * dOfs, const uint8_t *bytes, const size_t count) +{ + if (RDD == 0) for (size_t i = 0; i < count; i++, (*dOfs)++) { + if ((*dOfs) & 1) + codewords[(*cOfs)++] = bytes[(*dOfs) >> 1] >> 4; + else + codewords[(*cOfs)++] = bytes[(*dOfs) >> 1] & 0xf; + } else if (RDD == 1) for (size_t i = 0; i < count; i++, (*dOfs)++) { + if ((*dOfs) & 1) + codewords[(*cOfs)++] = encodeParity54(bytes[(*dOfs) >> 1] >> 4); + else + codewords[(*cOfs)++] = encodeParity54(bytes[(*dOfs) >> 1] & 0xf); + } else if (RDD == 2) for (size_t i = 0; i < count; i++, (*dOfs)++) { + if ((*dOfs) & 1) + codewords[(*cOfs)++] = encodeParity64(bytes[(*dOfs) >> 1] >> 4); + else + codewords[(*cOfs)++] = encodeParity64(bytes[(*dOfs) >> 1] & 0xf); + } else if (RDD == 3) for (size_t i = 0; i < count; i++, (*dOfs)++) { + if ((*dOfs) & 1) + codewords[(*cOfs)++] = encodeHamming74sx(bytes[(*dOfs) >> 1] >> 4); + else + codewords[(*cOfs)++] = encodeHamming74sx(bytes[(*dOfs) >> 1] & 0xf); + } else if (RDD == 4) for (size_t i = 0; i < count; i++, (*dOfs)++) { + if ((*dOfs) & 1) + codewords[(*cOfs)++] = encodeHamming84sx(bytes[(*dOfs) >> 1] >> 4); + else + codewords[(*cOfs)++] = encodeHamming84sx(bytes[(*dOfs) >> 1] & 0xf); + } +} + +// This function has been HEAVILY modified from the original. +// Note that there are references to SF6, 11 and 12, but they do not currently work. + +static int CreateMessageFromPayload( uint16_t * symbols, int * symbol_out_count, int max_symbols, int _sf, int _rdd, uint8_t * payload_plus_two_extra_crc_bytes, int payload_length ) +{ + //static int uctr = 0; + + int _whitening = 1; // Enable whitening + int _crc = 1; // Enable CRC. + + size_t PPM = _sf; + + int _explicit = 1; + + // TODO: https://dl.acm.org/doi/fullHtml/10.1145/3546869#sec-9 -- what about the corner cases for SF6, etc. + + // SF6 does NOT WORK + int nHeaderCodewords = 0; + if( _sf == 6 ) nHeaderCodewords = 6; + if( _sf == 7 ) nHeaderCodewords = 5; // CORRECT VALIDATED + if( _sf == 8 ) nHeaderCodewords = 6; // CORRECT VALIDATED + if( _sf == 9 ) nHeaderCodewords = 7; // CORRECT VALIDATED + if( _sf == 10 ) nHeaderCodewords = 8; // CORRECT VALIDATED + if( _sf == 11 ) nHeaderCodewords = 9; // ???? Probably Wrong + if( _sf == 12 ) nHeaderCodewords = 10; // ???? Probably Wrong + + int header_ppm_shift_up_by = 2; + // SF6 still isn't working. + // header does not reduce SF on SF <= 6 https://github.com/tapparelj/gr-lora_sdr/compare/master...feature/sf5_6_sx126x#diff-1821161335c7f28236eb88e3b8a3c84cce6997861cd847e87fbc9e270d338a37R68 + // Indirectly, to note, for SF > 6, the header is implicitly LDRO (the bottom 2 bits are ignored) + if( _sf < 7 ) header_ppm_shift_up_by = 0; + + int extra_codewords_due_to_header_padding = ( _sf == 7 || _sf == 6 /* CHECKME */ ) ? 1 : 0; + + int header_ppm = ( _sf - header_ppm_shift_up_by ); + int data_ppm = _sf; + + // XXX TODO: Investigate: I thought SF12 had an LDRO mode which made the PPM only 10. + // TODO: Compare to https://github.com/jkadbear/LoRaPHY/blob/master/LoRaPHY.m + + const size_t numCodewords = roundUp( ( payload_length + 2 * _crc ) * 2 + (_explicit ? nHeaderCodewords:0) + extra_codewords_due_to_header_padding, PPM); + const size_t numSymbols = N_HEADER_SYMBOLS + (numCodewords / PPM - 1) * (4 + _rdd); // header is always coded with 8/4 + uint8_t codewords[numCodewords]; + memset( codewords, 0, sizeof( codewords ) ); + + if( numSymbols >= max_symbols ) + { + //uprintf( "Error: Too many symbols to fit (%d/%d)\n", numSymbols, max_symbols ); + return -1; + } + + memset( symbols, 0, numSymbols * sizeof( symbols[0] ) ); + + size_t cOfs = 0; + size_t dOfs = 0; + + //std::vector codewords(numCodewords); + if (_crc) + { + uint16_t crc = sx1272DataChecksum( payload_plus_two_extra_crc_bytes, payload_length ); + payload_plus_two_extra_crc_bytes[payload_length] = crc & 0xff; + payload_plus_two_extra_crc_bytes[payload_length+1] = (crc >> 8) & 0xff; + } + + // Why does this disagree? https://www.Carloalbertoboano.Com/Documents/Yang22emu.Pdf + if (_explicit) { + uint8_t hdr[3]; + hdr[0] = payload_length; + hdr[1] = (_crc ? 1 : 0) | (_rdd << 1); + //static int k; + hdr[2] = + //k++; + headerChecksum(hdr); + + codewords[cOfs++] = encodeHamming84sx(hdr[0] >> 4); + codewords[cOfs++] = encodeHamming84sx(hdr[0] & 0xf); // length + codewords[cOfs++] = encodeHamming84sx(hdr[1] & 0xf); // crc / fec info + codewords[cOfs++] = encodeHamming84sx(hdr[2] >> 4); // checksum + codewords[cOfs++] = encodeHamming84sx(hdr[2] & 0xf); + + if( extra_codewords_due_to_header_padding > 1 ) + { + codewords[cOfs++] = 0; + } + if( extra_codewords_due_to_header_padding > 2 ) + { + codewords[cOfs++] = 0; + } + if( extra_codewords_due_to_header_padding > 3 ) + { + codewords[cOfs++] = 0; + } + } + + size_t cOfs1 = cOfs; + + // Header is encoded at 8/4 (4) + encodeFec( codewords, 4, &cOfs, &dOfs, payload_plus_two_extra_crc_bytes, PPM - cOfs ); + + // Whitening for the data that lives inside the header block. + if( _whitening ) + { + Sx1272ComputeWhitening(codewords + cOfs1, PPM - cOfs1, 0, HEADER_RDD); + } + + if (numCodewords > PPM) { + size_t cOfs2 = cOfs; + + encodeFec(codewords, _rdd, &cOfs, &dOfs, payload_plus_two_extra_crc_bytes, numCodewords-PPM); + + if (_whitening) { + Sx1272ComputeWhitening(codewords + cOfs2, numCodewords - PPM, PPM - cOfs1, _rdd); + } + } + + //interleave the codewords into symbols + int symbols_size = numSymbols; + + // TRICKY: Header is forced to a particularly slow mode. + diagonalInterleaveSx(codewords, header_ppm, symbols, header_ppm, HEADER_RDD); + + int i; + + if (numCodewords > header_ppm) { + diagonalInterleaveSx(codewords + nHeaderCodewords, numCodewords-nHeaderCodewords, symbols+N_HEADER_SYMBOLS, data_ppm, _rdd); + } + + //gray decode, when SF > PPM, pad out LSBs + uint16_t sym; + for( i = 0; i < symbols_size; i++ ) + { + //int is_header = (i < 8); + sym = symbols[i]; + sym = grayToBinary16(sym); + sym <<= (_sf - PPM); + symbols[i] = sym; // OR +1 + } + + // The first header symbols are all shifted by 2. + // XXX TODO Look here for SF6 stuff. + for( i = 0; i < N_HEADER_SYMBOLS; i++ ) + { + symbols[i] <<= header_ppm_shift_up_by; + } + + *symbol_out_count = symbols_size; + return 0; +} + +#endif + diff --git a/lib/aes-cbc-cmac.h b/lib/aes-cbc-cmac.h new file mode 100644 index 0000000..da7b4a3 --- /dev/null +++ b/lib/aes-cbc-cmac.h @@ -0,0 +1,193 @@ +/* Clean implementation of RFC4493 AES-CMAC in C, Public Domain by cnlohr + WARNING: This is not cryptographically hardened. + DO NOT USE THIS IN AN ENVIRONMENT WHERE SECURITY MATTERS + THIS IMPLEMENTATION IS HIGHLY SUCCEPTABLE TO TIMING ATTACKS + THIS IMPLEMENTATION DOES NOT USE HARDENED MEMORY. + + You may license this code under the unlicense, MIT-x11 or NewBSD licenses. + + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + 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 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. + For more information, please refer to + + Assumes a tiny-AES-c implementation for AES_init_ctx and AES_ECB_encrypt. + #define TINY_AES_ECB 1 + #include "tiny-AES-c.h" +*/ + +#include + +static void BlockLeftShift( uint8_t * blockout, const uint8_t * blockin ) +{ + int i; + int carry = 0; + for( i = 15; i >= 0; i-- ) + { + uint8_t bi = blockin[i]; + blockout[i] = (bi << 1) | carry; + carry = !!(bi & 0x80); + } +} + +static void BlockXor( uint8_t * out, const uint8_t * in, const uint8_t * inb ) +{ + int i; + for( i = 0; i < 16; i++ ) + out[i] = in[i] ^ inb[i]; +} + + +static void AES_CMAC( const uint8_t *key, const uint8_t *input, int length, + uint8_t *mac ) +{ + struct AES_ctx K; + AES_init_ctx( &K, key); + + int i; + // Based on Figure 2.2, GenerateSubKey + /* + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + Algorithm Generate_Subkey + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + + Input : K (128-bit key) + + + Output : K1 (128-bit first subkey) + + + K2 (128-bit second subkey) + + +-------------------------------------------------------------------+ + + + + + Constants: const_Zero is 0x00000000000000000000000000000000 + + + const_Rb is 0x00000000000000000000000000000087 + + + Variables: L for output of AES-128 applied to 0^128 + + + + + + Step 1. L := AES-128(K, const_Zero); + + + Step 2. if MSB(L) is equal to 0 + + + then K1 := L << 1; + + + else K1 := (L << 1) XOR const_Rb; + + + Step 3. if MSB(K1) is equal to 0 + + + then K2 := K1 << 1; + + + else K2 := (K1 << 1) XOR const_Rb; + + + Step 4. return K1, K2; + + + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + */ + const uint8_t const_Rb[AES_BLOCKLEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }; + uint8_t K1[AES_BLOCKLEN]; + uint8_t K2[AES_BLOCKLEN]; + { + uint8_t L[AES_BLOCKLEN] = { 0 }; + AES_ECB_encrypt( &K, L ); + + BlockLeftShift( K1, L ); + if( L[0] & 0x80 ) + BlockXor( K1, K1, const_Rb ); + + BlockLeftShift( K2, K1 ); + if( K1[0] & 0x80 ) + BlockXor( K2, K2, const_Rb ); + } + + // Based on figure 2.3, AES-CMAC + /* + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + Algorithm AES-CMAC + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + + Input : K ( 128-bit key ) + + + : M ( message to be authenticated ) + + + : len ( length of the message in octets ) + + + Output : T ( message authentication code ) + + + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + Constants: const_Zero is 0x00000000000000000000000000000000 + + + const_Bsize is 16 + + + + + + Variables: K1, K2 for 128-bit subkeys + + + M_i is the i-th block (i=1..ceil(len/const_Bsize)) + + + M_last is the last block xor-ed with K1 or K2 + + + n for number of blocks to be processed + + + r for number of octets of last block + + + flag for denoting if last block is complete or not + + + + + + Step 1. (K1,K2) := Generate_Subkey(K); + + + Step 2. n := ceil(len/const_Bsize); + + + Step 3. if n = 0 + + + then + + + n := 1; + + + flag := false; + + + else + + + if len mod const_Bsize is 0 + + + then flag := true; + + + else flag := false; + + + + + + Step 4. if flag is true + + + then M_last := M_n XOR K1; + + + else M_last := padding(M_n) XOR K2; + + + Step 5. X := const_Zero; + + + Step 6. for i := 1 to n-1 do + + + begin + + + Y := X XOR M_i; + + + X := AES-128(K,Y); + + + end + + + Y := M_last XOR X; + + + T := AES-128(K,Y); + + + Step 7. return T; + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + */ + uint8_t M_last[AES_BLOCKLEN]; + + int remainder = length % AES_BLOCKLEN; + int flag = !(remainder); // If evenly divisible, set to true. + int n = ( length + AES_BLOCKLEN - 1 ) / AES_BLOCKLEN; + if( n == 0 ) + { + n = 1; + flag = 0; // Unless 0 size payload. + } + + const uint8_t * in_last = &input[(n-1)*AES_BLOCKLEN]; + if( flag ) + { + BlockXor( M_last, in_last, K1 ); + } + else + { + memcpy( M_last, in_last, remainder ); + memset( M_last + remainder + 1, 0, AES_BLOCKLEN - remainder - 1 ); + M_last[remainder] = 0x80; + BlockXor( M_last, M_last, K2 ); + } + + uint8_t X[AES_BLOCKLEN] = { 0 }; + for( i = 0; i < n-1; i++ ) + { + BlockXor( X, X, &input[i*AES_BLOCKLEN] ); + AES_ECB_encrypt( &K, X ); + } + + BlockXor( mac, M_last, X ); + AES_ECB_encrypt( &K, mac ); +} + + + diff --git a/lib/lorawan_simple.h b/lib/lorawan_simple.h new file mode 100644 index 0000000..80c99f2 --- /dev/null +++ b/lib/lorawan_simple.h @@ -0,0 +1,160 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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. +*/ + +#ifndef _LORAWAN_SIMPLE_H +#define _LORAWAN_SIMPLE_H + +#include +#include + +// Configuration needed for aes-cbc-cmac.h +#define TINY_AES_C_IMPLEMENTATION + +#define TINY_AES_ECB 1 +#include "tiny-AES-c.h" +#include "aes-cbc-cmac.h" + +static int GenerateLoRaWANPacket( uint8_t * raw_payload_with_b0, const uint8_t * inner_payload_raw, int inner_payload_len, const uint8_t * payload_key, const uint8_t * network_skey, const uint8_t * devaddress, int frame ) +{ + int i; + uint8_t * raw_payload = raw_payload_with_b0 + 16; + uint8_t * pl = raw_payload; + + struct AES_ctx payload_key_ctx; + AES_init_ctx( &payload_key_ctx, payload_key ); + + // MAC header + // 010 Unconfirmed data uplink. + // 000 RFU + // 00 Major Version + *(pl++) = ( 0b01000000 ); + + + // Frame header + // Device address (4 bytes) + memcpy( pl, devaddress, 4 ); + pl += 4; + + // Frame Control + // MSB + // 0 = ADR (cannot do rate adaptation) + // 0 = Not confirming ADR. + // 0 = ACK + // 0 = Class B (we are not a class B device because we can't schedule downlinks) + // 0000 = fopts length (no fopts) + // LSB + *(pl++) = 0b00000000; + + // Frame Count + *(pl++) = frame; + *(pl++) = frame>>8; + + // Frame Port + *(pl++) = 1; // Port (1-223 are application specific) + + + int padded_pad_length = ( inner_payload_len + AES_BLOCKLEN - 1 ) & (~(AES_BLOCKLEN-1)); + int nr_blocks = padded_pad_length / AES_BLOCKLEN; + uint8_t pad[padded_pad_length]; + for( i = 0; i < nr_blocks; i++ ) + { + // Add CMAC. Construct b0 + uint8_t * Ai = &pad[i*AES_BLOCKLEN]; + *(Ai++) = 0x01; + *(Ai++) = 0; + *(Ai++) = 0; + *(Ai++) = 0; + *(Ai++) = 0; + + *(Ai++) = 0; // Uplink = 0 + + *(Ai++) = devaddress[0]; + *(Ai++) = devaddress[1]; + *(Ai++) = devaddress[2]; + *(Ai++) = devaddress[3]; + + *(Ai++) = (frame>>0) & 0xff; + *(Ai++) = (frame>>8) & 0xff; + *(Ai++) = (frame>>16) & 0xff; + *(Ai++) = (frame>>24) & 0xff; + *(Ai++) = 0; + + *(Ai++) = i+1; + } + for( i = 0; i < nr_blocks; i++ ) + { + AES_ECB_encrypt( &payload_key_ctx, &pad[i*AES_BLOCKLEN] ); + } + +// uint8_t * start_of_payload = pl; + + for( i = 0; i < inner_payload_len; i++ ) + { + *(pl++) = pad[i] ^ inner_payload_raw[i]; + } + + int to_cmac_size = pl - raw_payload_with_b0; + int length_of_frame_without_b0 = pl - raw_payload; + + uint8_t * b0 = raw_payload_with_b0; + *(b0++) = 0x49; + *(b0++) = 0x00; + *(b0++) = 0x00; + *(b0++) = 0x00; + *(b0++) = 0x00; + *(b0++) = 0x00; + + *(b0++) = devaddress[0]; + *(b0++) = devaddress[1]; + *(b0++) = devaddress[2]; + *(b0++) = devaddress[3]; + + *(b0++) = (frame>>0) & 0xff; + *(b0++) = (frame>>8) & 0xff; + *(b0++) = (frame>>16) & 0xff; + *(b0++) = (frame>>24) & 0xff; + *(b0++) = 0x00; + *(b0++) = length_of_frame_without_b0; + + uint8_t mac[AES_BLOCKLEN]; + //printf( "To CMAC: %d\n", to_cmac_size ); + //for ( i = 0; i < to_cmac_size; i++ ) + //{ + // printf( "%02x ", raw_payload_with_b0[i] ); + //} + //printf( "\n" ); + + AES_CMAC( network_skey, raw_payload_with_b0, to_cmac_size, mac ); + + *(pl++) = mac[0]; + *(pl++) = mac[1]; + *(pl++) = mac[2]; + *(pl++) = mac[3]; + + //printf( "MAC %02x%02x%02x%02x %02x%02x%02x%02x\n", mac[0], mac[1], mac[2], mac[3], mac[12], mac[13], mac[14], mac[15] ); + + return pl - raw_payload_with_b0 - 16; +} + +#endif diff --git a/lib/rf_data_gen.h b/lib/rf_data_gen.h new file mode 100644 index 0000000..7bae90a --- /dev/null +++ b/lib/rf_data_gen.h @@ -0,0 +1,344 @@ +/** + +MIT-like-non-ai-license + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 two following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +In addition the following restrictions apply: + +1. The Software and any modifications made to it may not be used for the +purpose of training or improving machine learning algorithms, including but not +limited to artificial intelligence, natural language processing, or data +mining. This condition applies to any derivatives, modifications, or updates +based on the Software code. Any usage of the Software in an AI-training dataset +is considered a breach of this License. + +2. The Software may not be included in any dataset used for training or +improving machine learning algorithms, including but not limited to artificial +intelligence, natural language processing, or data mining. + +3. Any person or organization found to be in violation of these restrictions +will be subject to legal action and may be held liable for any damages +resulting from such use. + +If any term is unenforcable, other terms remain in-force. + +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. + +*/ + +// This file is code, but intended to be included into a .c file that +// does #define's for a specific fitness. Below is an example .c file +// that this could be included into to generate the bit table. It is +// from an ESP8266 example, but other specifics can be specified on a +// per-processor basis. + +/* + +const double center_frequency = 904.1; +const double bw = .125; +const uint32_t memory_offset = 0x20000; +#define SF_NUMBER 7 + +#if SF_NUMBER < 7 +#warning SF6 still does not work :( +#endif + +#define SPI_DIV 1 + +// Funny modes: +/// 80MHz, SF8, SPI_DIV 5 @903.9/904.1 produces hilarious mirror images around 904.0 + +#if MAIN_MHZ == 80 +const double sample_rate = 1040.0/13.0/SPI_DIV; +#if ( SF_NUMBER > 8 ) +#error Not enough ram for chirp table +#endif + +#elif MAIN_MHZ == 115 +const double sample_rate = 1040.0/9.0/SPI_DIV; +#if ( SF_NUMBER > 8 ) +#error Not enough ram for chirp table +#endif + +#elif MAIN_MHZ == 52 +const double sample_rate = 1040.0/20.0/SPI_DIV; +#if ( SF_NUMBER > 9 ) +#error Not enough ram for chirp table +#endif + +#elif MAIN_MHZ == 173 +const double sample_rate = 1040.0/6.0/SPI_DIV; +#if ( SF_NUMBER > 7 ) +#error Not enough ram for chirp table +#endif + +#else +#error Unknown Clock Rate +#endif + + +EXTRA OPTIONS +#define USE_16_BITS +*/ + +#include +#include +#include + + +const double chirp_begin = center_frequency-bw/2; +const double chirp_end = center_frequency+bw/2; + +#ifndef MEM_MAX_BYTES +#define MEM_MAX_BYTES 2000000 +#endif + +#ifndef SF_SYMBOL_TIME +#define SF_SYMBOL_TIME 0.000001 +#endif + +const double chirp_length_seconds = (8<= 1 ) + { + // When going off the top frequency, start over at the bottom. + placeInSamples -= 1; + } + + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + + // These are the key lines here. This is what actually decides the current + // frequency and figures out what the given bit in a position should be. + // I use 0.1 as an offset because it seems to have some beneficial behaviors + // but 0.0 also seems to work really well. You can artifically reduce the + // amplituide of the output signal by changing the offset in the comparison + // on the last line of this section. + + double current_f = ( placeInSamples ) * ( fEnd - fStart ) + fStart; + phase += 3.1415926 * 2.0 * current_f / sample_rate; + int bit = sin( phase ) > 0.1; // HINT: if you want to mix multiple signals, add a DC offset here. + + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + + sample_word |= !!bit; + samplect++; + if( samplect == NUMBITS ) + { +#ifdef USE_16_BITS + // sample_word = ((sample_word>>8)&0xff) | ((sample_word<<8)&0xff00); + // sample_word = flipBits( sample_word, 16 ); + fprintf( fcba, "0x%04x,%c", sample_word, ((words & 0xf) != 0xf)?' ':'\n' ); +#else + fprintf( fcba, "0x%08x,%c", sample_word, ((words & 0xf) != 0xf)?' ':'\n' ); +#endif + fwrite( &sample_word, 1, NUMBITS/8, fd ); + words++; + sample_word = 0; + samplect = 0; + if( samples < sampletotal ) + words_nominal = words; + + if( samples >= sampletotal + bleedover*32 ) + { + break; + } + } + sample_word <<= 1; + } + } +} + +#ifndef ATTRIBUTE_FOR_DATA +#define ATTRIBUTE_FOR_DATA +#endif + +int gen_buffer_files() +{ + fcba = fopen( "chirpbuff.h", "w" ); + fd = fopen( "chirpbuff.dat", "w" ); + fCBI = fopen( "chirpbuffinfo.h", "w" ); + +#ifdef USE_16_BITS + fprintf( fcba, "const uint16_t chirpbuff[] " ATTRIBUTE_FOR_DATA " = {\n" ); +#else + fprintf( fcba, "const uint32_t chirpbuff[] " ATTRIBUTE_FOR_DATA " = {\n" ); +#endif + + + + int quarter_chirp_length_bits = (int)(sampletotal/4.0+0.5); + int factor = 0; + int is_perfect_divisor = 0; + int i; + + // DMA size words, when multiplied out should be SMALLER than the + // overall length of our message, so that we can trim off the last few + // words sometimes, to average out to the right bitrate. + + // So, we need to pick a number that when multiplied out, ends up + // slightly larger than IDEAL_CHIRP_LENGTH_BITS. But not too much so. + + // First try to find a perfect divisor, if we can find a perfect divisor, + // then no weird fixup stuff needs to be done. + + int seeking_perfect_divisor = 1; + bleedover = 0; + +retry_without_seek: + + printf( "Searching for a divisor for %d\n", quarter_chirp_length_bits ); + for( i = 511; i > 100; i-- ) + { + int nr_to_div = (quarter_chirp_length_bits / 32 + 32) / i; + int num_bits_default = i * 32 * nr_to_div; + int leftover = num_bits_default - quarter_chirp_length_bits; + //fprintf( stderr, "%d %d %d [%d] --> %d\n", i, nr_to_div, num_bits_default, quarter_chirp_length_bits, leftover ); + if( leftover < 32*nr_to_div && + ( seeking_perfect_divisor ? (leftover == 0) : (leftover >= 0)) ) + { + // Make sure we aren't more than 1 32-bit word too large + fprintf( stderr, "Found %s divisor: %d (%d - %d = %d)\n", + (leftover == 0)?"PERFECT" : "OK", + i, + num_bits_default, + quarter_chirp_length_bits, + num_bits_default - quarter_chirp_length_bits ); + factor = i; + + //XXX TODO: I think this bleedover calc is wrong. Should investigate? + bleedover = num_bits_default/32; + is_perfect_divisor = leftover == 0; + break; + } + } + + if( seeking_perfect_divisor && !factor ) + { + seeking_perfect_divisor = 0; + goto retry_without_seek; + } + + if( !factor ) + { + fprintf( stderr, "Error: No factor of %d found, you may have to do something clever in rf_data_gen.c\n", quarter_chirp_length_bits ); + return -9; + } + + // For a given word, it is shifted out MSB (Bit and byte) first + GenChirp( chirp_begin, chirp_end ); + int sample_word_median = words; + int quarter_chirp_length = ((words_nominal+2)/4); + int reverse_start = words; + words = 0; + GenChirp( chirp_end, chirp_begin ); + + fprintf( fcba, "};\n" ); + fclose( fcba ); + fclose( fd ); + +#ifdef USE_16_BITS + int bytes_total = 2*(words+sample_word_median); + fprintf( stderr, "Wrote out %d uint16_t's.\n", words + sample_word_median ); +#else + int bytes_total = 4*(words+sample_word_median); + fprintf( stderr, "Wrote out %d uint32_t's.\n", words + sample_word_median ); +#endif + + if( bytes_total > MEM_MAX_BYTES ) + { + fprintf( stderr, "ERROR: Your table is too big (trying to write out %d bytes, please adjust SF/BW/clock rate settings)\n", bytes_total ); + } + + fprintf( fCBI, "#define CHIRPLENGTH_WORDS (%d)\n", words_nominal ); + fprintf( fCBI, "#define MEMORY_START_OFFSET_BYTES (0x%08x)\n", memory_offset ); + fprintf( fCBI, "#define REVERSE_START_OFFSET_BYTES (0x%08x)\n", memory_offset + reverse_start * NUMBITS/8 ); + fprintf( fCBI, "#define QUARTER_CHIRP_LENGTH_WORDS (%d)\n", (int)(quarter_chirp_length) ); + fprintf( fCBI, "#define IDEAL_QUARTER_CHIRP_LENGTH_BITS (%d)\n", quarter_chirp_length_bits ); + fprintf( fCBI, "#define CHIRPLENGTH_WORDS_WITH_PADDING (%d)\n", sample_word_median ); + fprintf( fCBI, "#define STRIPE_BLEEDOVER_WORDS (%d)\n", bleedover ); + fprintf( fCBI, "#define TARGET_SAMPLE_COUNT_BITS (%d)\n", (int)sampletotal ); + fprintf( fCBI, "#define DMA_SIZE_WORDS (%d)\n", factor ); + fprintf( fCBI, "#define NUM_DMAS_PER_QUARTER_CHIRP (%d)\n", quarter_chirp_length/factor+((is_perfect_divisor)?0:1) ); + fprintf( fCBI, "#define SF_NUMBER %d\n", SF_NUMBER ); + fprintf( fCBI, "#define SPI_DIV %d\n", SPI_DIV ); + + if( factor & 1 ) + fprintf( fCBI, "#define DMA_SIZE_WORDS_DIVISIBLE_BY_TWO 0\n" ); + else + fprintf( fCBI, "#define DMA_SIZE_WORDS_DIVISIBLE_BY_TWO 1\n" ); + + if( factor & 3 ) + fprintf( fCBI, "#define DMA_SIZE_WORDS_DIVISIBLE_BY_FOUR 0\n" ); + else + fprintf( fCBI, "#define DMA_SIZE_WORDS_DIVISIBLE_BY_FOUR 1\n" ); + + +#ifdef USE_EXTERNAL_CLOCK + fprintf( fCBI, "#define USE_EXTERNAL_CLOCK\n" ); +#endif + if( is_perfect_divisor ) + fprintf( fCBI, "#define FOUND_PERFECT_DIVISOR\n" ); + fclose( fCBI ); +} diff --git a/lib/tiny-AES-c.h b/lib/tiny-AES-c.h new file mode 100644 index 0000000..d8b4eec --- /dev/null +++ b/lib/tiny-AES-c.h @@ -0,0 +1,704 @@ +/* + Header-only version of tiny-AES-c https://github.com/kokke/tiny-AES-c/blob/master/aes.c + + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + 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 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. + + For more information, please refer to +*/ + +#ifndef _TINY_AES_C_H_ +#define _TINY_AES_C_H_ + +#include +#include + +// If you want to use this library: +// #define TINY_AES_C_IMPLEMENTATION + +// #define the macros below to 1/0 to enable/disable the mode of operation. +// +// CBC enables AES encryption in CBC-mode of operation. +// CTR enables encryption in counter-mode. +// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously. + +// The #ifndef-guard allows it to be configured before #include'ing or at compile time. +#ifndef TINY_AES_CBC + #define TINY_AES_CBC 1 +#endif + +#ifndef TINY_AES_ECB + #define TINY_AES_ECB 1 +#endif + +#ifndef TINY_AES_CTR + #define TINY_AES_CTR 1 +#endif + +#if !defined( AES128 ) && !defined( AES192 ) && !defined( AES256 ) +#define AES128 1 +//#define AES192 1 +//#define AES256 1 +#endif + +#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only + +#if defined(AES256) && (AES256 == 1) + #define AES_KEYLEN 32 + #define AES_keyExpSize 240 +#elif defined(AES192) && (AES192 == 1) + #define AES_KEYLEN 24 + #define AES_keyExpSize 208 +#else + #define AES_KEYLEN 16 // Key length in bytes + #define AES_keyExpSize 176 +#endif + +struct AES_ctx +{ + uint8_t RoundKey[AES_keyExpSize]; +#if (defined(TINY_AES_CBC) && (TINY_AES_CBC == 1)) || (defined(TINY_AES_CTR) && (TINY_AES_CTR == 1)) + uint8_t Iv[AES_BLOCKLEN]; +#endif +}; + +void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key); +#if (defined(TINY_AES_CBC) && (TINY_AES_CBC == 1)) || (defined(TINY_AES_CTR) && (TINY_AES_CTR == 1)) +void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv); +void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv); +#endif + +#if defined(TINY_AES_ECB) && (TINY_AES_ECB == 1) +// buffer size is exactly AES_BLOCKLEN bytes; +// you need only AES_init_ctx as IV is not used in ECB +// NB: ECB is considered insecure for most uses +void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf); +void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf); + +#endif // #if defined(TINY_AES_ECB) && (TINY_AES_ECB == !) + + +#if defined(TINY_AES_CBC) && (TINY_AES_CBC == 1) +// buffer size MUST be mutile of AES_BLOCKLEN; +// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme +// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv() +// no IV should ever be reused with the same key +void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); +void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); + +#endif // #if defined(TINY_AES_CBC) && (TINY_AES_CBC == 1) + + +#if defined(TINY_AES_CTR) && (TINY_AES_CTR == 1) + +// Same function for encrypting as for decrypting. +// IV is incremented for every block, and used after encryption as XOR-compliment for output +// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme +// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv() +// no IV should ever be reused with the same key +void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length); + +#endif // #if defined(TINY_AES_CTR) && (TINY_AES_CTR == 1) + + + + +#ifdef TINY_AES_C_IMPLEMENTATION + + +/* + +This is an implementation of the AES algorithm, specifically ECB, TINY_AES_CTR and CBC mode. +Block size can be chosen in aes.h - available choices are AES128, AES192, AES256. + +The implementation is verified against the test vectors in: + National Institute of Standards and Technology Special Publication 800-38A 2001 ED + +ECB-AES128 +---------- + + plain-text: + 6bc1bee22e409f96e93d7e117393172a + ae2d8a571e03ac9c9eb76fac45af8e51 + 30c81c46a35ce411e5fbc1191a0a52ef + f69f2445df4f9b17ad2b417be66c3710 + + key: + 2b7e151628aed2a6abf7158809cf4f3c + + resulting cipher + 3ad77bb40d7a3660a89ecaf32466ef97 + f5d3d58503b9699de785895a96fdbaaf + 43b1cd7f598ece23881b00e3ed030688 + 7b0c785e27e8ad3f8223207104725dd4 + + +NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) + You should pad the end of the string with zeros if this is not the case. + For AES192/256 the key size is proportionally larger. + +*/ + + +/*****************************************************************************/ +/* Includes: */ +/*****************************************************************************/ +#include // CBC mode, for memset + +/*****************************************************************************/ +/* Defines: */ +/*****************************************************************************/ +// The number of columns comprising a state in AES. This is a constant in AES. Value=4 +#define Nb 4 + +#if defined(AES256) && (AES256 == 1) + #define Nk 8 + #define Nr 14 +#elif defined(AES192) && (AES192 == 1) + #define Nk 6 + #define Nr 12 +#else + #define Nk 4 // The number of 32 bit words in a key. + #define Nr 10 // The number of rounds in AES Cipher. +#endif + +// jcallan@github points out that declaring Multiply as a function +// reduces code size considerably with the Keil ARM compiler. +// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3 +#ifndef MULTIPLY_AS_A_FUNCTION + #define MULTIPLY_AS_A_FUNCTION 0 +#endif + + + + +/*****************************************************************************/ +/* Private variables: */ +/*****************************************************************************/ +// state - array holding the intermediate results during decryption. +typedef uint8_t state_t[4][4]; + + + +// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM +// The numbers below can be computed dynamically trading ROM for RAM - +// This can be useful in (embedded) bootloader applications, where ROM is often limited. +static const uint8_t sbox[256] = { + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; + +#if (defined(TINY_AES_CBC) && TINY_AES_CBC == 1) || (defined(TINY_AES_ECB) && TINY_AES_ECB == 1) +static const uint8_t rsbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; +#endif + +// The round constant word array, Rcon[i], contains the values given by +// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) +static const uint8_t Rcon[11] = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + +/* + * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12), + * that you can remove most of the elements in the Rcon array, because they are unused. + * + * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon + * + * "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed), + * up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm." + */ + + +/*****************************************************************************/ +/* Private functions: */ +/*****************************************************************************/ +/* +static uint8_t getSBoxValue(uint8_t num) +{ + return sbox[num]; +} +*/ +#define getSBoxValue(num) (sbox[(num)]) + +// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. +static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key) +{ + unsigned i, j, k; + uint8_t tempa[4]; // Used for the column/row operations + + // The first round key is the key itself. + for (i = 0; i < Nk; ++i) + { + RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; + RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; + RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; + RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; + } + + // All other round keys are found from the previous round keys. + for (i = Nk; i < Nb * (Nr + 1); ++i) + { + { + k = (i - 1) * 4; + tempa[0]=RoundKey[k + 0]; + tempa[1]=RoundKey[k + 1]; + tempa[2]=RoundKey[k + 2]; + tempa[3]=RoundKey[k + 3]; + + } + + if (i % Nk == 0) + { + // This function shifts the 4 bytes in a word to the left once. + // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] + + // Function RotWord() + { + const uint8_t u8tmp = tempa[0]; + tempa[0] = tempa[1]; + tempa[1] = tempa[2]; + tempa[2] = tempa[3]; + tempa[3] = u8tmp; + } + + // SubWord() is a function that takes a four-byte input word and + // applies the S-box to each of the four bytes to produce an output word. + + // Function Subword() + { + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + + tempa[0] = tempa[0] ^ Rcon[i/Nk]; + } +#if defined(AES256) && (AES256 == 1) + if (i % Nk == 4) + { + // Function Subword() + { + tempa[0] = getSBoxValue(tempa[0]); + tempa[1] = getSBoxValue(tempa[1]); + tempa[2] = getSBoxValue(tempa[2]); + tempa[3] = getSBoxValue(tempa[3]); + } + } +#endif + j = i * 4; k=(i - Nk) * 4; + RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0]; + RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1]; + RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2]; + RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3]; + } +} + +void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key) +{ + KeyExpansion(ctx->RoundKey, key); +} +#if (defined(TINY_AES_CBC) && (TINY_AES_CBC == 1)) || (defined(TINY_AES_CTR) && (TINY_AES_CTR == 1)) +void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv) +{ + KeyExpansion(ctx->RoundKey, key); + memcpy (ctx->Iv, iv, AES_BLOCKLEN); +} +void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv) +{ + memcpy (ctx->Iv, iv, AES_BLOCKLEN); +} +#endif + +// This function adds the round key to state. +// The round key is added to the state by an XOR function. +static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey) +{ + uint8_t i,j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j]; + } + } +} + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +static void SubBytes(state_t* state) +{ + uint8_t i, j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[j][i] = getSBoxValue((*state)[j][i]); + } + } +} + +// The ShiftRows() function shifts the rows in the state to the left. +// Each row is shifted with different offset. +// Offset = Row number. So the first row is not shifted. +static void ShiftRows(state_t* state) +{ + uint8_t temp; + + // Rotate first row 1 columns to left + temp = (*state)[0][1]; + (*state)[0][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[3][1]; + (*state)[3][1] = temp; + + // Rotate second row 2 columns to left + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + // Rotate third row 3 columns to left + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[3][3]; + (*state)[3][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[1][3]; + (*state)[1][3] = temp; +} + +static uint8_t xtime(uint8_t x) +{ + return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); +} + +// MixColumns function mixes the columns of the state matrix +static void MixColumns(state_t* state) +{ + uint8_t i; + uint8_t Tmp, Tm, t; + for (i = 0; i < 4; ++i) + { + t = (*state)[i][0]; + Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; + Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; + Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; + Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; + Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; + } +} + +// Multiply is used to multiply numbers in the field GF(2^8) +// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary +// The compiler seems to be able to vectorize the operation better this way. +// See https://github.com/kokke/tiny-AES-c/pull/34 +#if MULTIPLY_AS_A_FUNCTION +static uint8_t Multiply(uint8_t x, uint8_t y) +{ + return (((y & 1) * x) ^ + ((y>>1 & 1) * xtime(x)) ^ + ((y>>2 & 1) * xtime(xtime(x))) ^ + ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ + ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */ + } +#else +#define Multiply(x, y) \ + ( ((y & 1) * x) ^ \ + ((y>>1 & 1) * xtime(x)) ^ \ + ((y>>2 & 1) * xtime(xtime(x))) ^ \ + ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ + ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ + +#endif + +#if (defined(TINY_AES_CBC) && TINY_AES_CBC == 1) || (defined(TINY_AES_ECB) && TINY_AES_ECB == 1) +/* +static uint8_t getSBoxInvert(uint8_t num) +{ + return rsbox[num]; +} +*/ +#define getSBoxInvert(num) (rsbox[(num)]) + +// MixColumns function mixes the columns of the state matrix. +// The method used to multiply may be difficult to understand for the inexperienced. +// Please use the references to gain more information. +static void InvMixColumns(state_t* state) +{ + int i; + uint8_t a, b, c, d; + for (i = 0; i < 4; ++i) + { + a = (*state)[i][0]; + b = (*state)[i][1]; + c = (*state)[i][2]; + d = (*state)[i][3]; + + (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); + (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); + (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); + (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); + } +} + + +// The SubBytes Function Substitutes the values in the +// state matrix with values in an S-box. +static void InvSubBytes(state_t* state) +{ + uint8_t i, j; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + (*state)[j][i] = getSBoxInvert((*state)[j][i]); + } + } +} + +static void InvShiftRows(state_t* state) +{ + uint8_t temp; + + // Rotate first row 1 columns to right + temp = (*state)[3][1]; + (*state)[3][1] = (*state)[2][1]; + (*state)[2][1] = (*state)[1][1]; + (*state)[1][1] = (*state)[0][1]; + (*state)[0][1] = temp; + + // Rotate second row 2 columns to right + temp = (*state)[0][2]; + (*state)[0][2] = (*state)[2][2]; + (*state)[2][2] = temp; + + temp = (*state)[1][2]; + (*state)[1][2] = (*state)[3][2]; + (*state)[3][2] = temp; + + // Rotate third row 3 columns to right + temp = (*state)[0][3]; + (*state)[0][3] = (*state)[1][3]; + (*state)[1][3] = (*state)[2][3]; + (*state)[2][3] = (*state)[3][3]; + (*state)[3][3] = temp; +} +#endif // #if (defined(TINY_AES_CBC) && TINY_AES_CBC == 1) || (defined(TINY_AES_ECB) && TINY_AES_ECB == 1) + +// Cipher is the main function that encrypts the PlainText. +static void Cipher(state_t* state, const uint8_t* RoundKey) +{ + uint8_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey(0, state, RoundKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr rounds are executed in the loop below. + // Last one without MixColumns() + for (round = 1; ; ++round) + { + SubBytes(state); + ShiftRows(state); + if (round == Nr) { + break; + } + MixColumns(state); + AddRoundKey(round, state, RoundKey); + } + // Add round key to last round + AddRoundKey(Nr, state, RoundKey); +} + +#if (defined(TINY_AES_CBC) && TINY_AES_CBC == 1) || (defined(TINY_AES_ECB) && TINY_AES_ECB == 1) +static void InvCipher(state_t* state, const uint8_t* RoundKey) +{ + uint8_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey(Nr, state, RoundKey); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr rounds are executed in the loop below. + // Last one without InvMixColumn() + for (round = (Nr - 1); ; --round) + { + InvShiftRows(state); + InvSubBytes(state); + AddRoundKey(round, state, RoundKey); + if (round == 0) { + break; + } + InvMixColumns(state); + } + +} +#endif // #if (defined(TINY_AES_CBC) && TINY_AES_CBC == 1) || (defined(TINY_AES_ECB) && TINY_AES_ECB == 1) + +/*****************************************************************************/ +/* Public functions: */ +/*****************************************************************************/ +#if defined(TINY_AES_ECB) && (TINY_AES_ECB == 1) + + +void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf) +{ + // The next function call encrypts the PlainText with the Key using AES algorithm. + Cipher((state_t*)buf, ctx->RoundKey); +} + +void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf) +{ + // The next function call decrypts the PlainText with the Key using AES algorithm. + InvCipher((state_t*)buf, ctx->RoundKey); +} + + +#endif // #if defined(TINY_AES_ECB) && (TINY_AES_ECB == 1) + + + + + +#if defined(TINY_AES_CBC) && (TINY_AES_CBC == 1) + + +static void XorWithIv(uint8_t* buf, const uint8_t* Iv) +{ + uint8_t i; + for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size + { + buf[i] ^= Iv[i]; + } +} + +void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length) +{ + size_t i; + uint8_t *Iv = ctx->Iv; + for (i = 0; i < length; i += AES_BLOCKLEN) + { + XorWithIv(buf, Iv); + Cipher((state_t*)buf, ctx->RoundKey); + Iv = buf; + buf += AES_BLOCKLEN; + } + /* store Iv in ctx for next call */ + memcpy(ctx->Iv, Iv, AES_BLOCKLEN); +} + +void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length) +{ + size_t i; + uint8_t storeNextIv[AES_BLOCKLEN]; + for (i = 0; i < length; i += AES_BLOCKLEN) + { + memcpy(storeNextIv, buf, AES_BLOCKLEN); + InvCipher((state_t*)buf, ctx->RoundKey); + XorWithIv(buf, ctx->Iv); + memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN); + buf += AES_BLOCKLEN; + } + +} + +#endif // #if defined(TINY_AES_CBC) && (TINY_AES_CBC == 1) + + + +#if defined(TINY_AES_CTR) && (TINY_AES_CTR == 1) + +/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */ +void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length) +{ + uint8_t buffer[AES_BLOCKLEN]; + + size_t i; + int bi; + for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi) + { + if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */ + { + + memcpy(buffer, ctx->Iv, AES_BLOCKLEN); + Cipher((state_t*)buffer,ctx->RoundKey); + + /* Increment Iv and handle overflow */ + for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi) + { + /* inc will overflow */ + if (ctx->Iv[bi] == 255) + { + ctx->Iv[bi] = 0; + continue; + } + ctx->Iv[bi] += 1; + break; + } + bi = 0; + } + + buf[i] = (buf[i] ^ buffer[bi]); + } +} + +#endif // #if defined(TINY_AES_CTR) && (TINY_AES_CTR == 1) + + + +#endif + +#endif // _AES_H_ diff --git a/resources/36mhz-up-the-spectrum.png b/resources/36mhz-up-the-spectrum.png new file mode 100644 index 0000000000000000000000000000000000000000..171fb5a1edb7030507ab2d6bc1a7f150375ddcb9 GIT binary patch literal 65490 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 WP|g|>)1BOcgqL!vvZXJK0{%d zOfs1>C!5_pdv<^C^Sqk~O?3qvObSc@0Dz;U2+{@skUHU?ThS5W@4~H`M*sjqsI9E5 zrjo2Ios)~Bm92v%0Kl5ymms0oBTdz3qEiGU34cTEJgAxFfJWk6{()5{Oq-+r(A4FC zRM1vY+lUHfJ~)In>H`|7^(Sg0l=tUIy^CE+Q*z2rCfYUxTV2jltA8OYZAhV3DWz5# zRGM!`1{sMyb9b<#8gC5X%RuRw`E+trN_5VtOzzGvZn%f*S|^@GP?Lj)06B_O*1ydN z9PuX{z@mG8o4gz>GwRPLwo(rx2m&^N?=b-=o01?wo_Jwa z+}Gpwrh%s|yc3)HR}atIwk(s8McSo1J&G7~iLuyUvN+azTmgze5oC14P}Fr4X%>uN zx>$LAt9!G@o)rd$iQ(bl^5ODG)4GH#a_=)5TW^G5LEg*jhrBgcGy132a&9} z3M-8qq38kWZFUes^#hMh04g~k2qM0EgcHqm)=A%B8d%JL=u&mN^VE9_`uNK_4oSv- z8Dc!BMm!g#;hm!I?f&y)W%{zBb0lgcnP7;VDIkuk^>&X;#5BoJj|NH6Xdij=Yh!C` z<6}`W*vKgPBK2D;15KZf>K{ zdS#OO(S1+gmkMIh3lZdFFW00Q?$&o5b}c0;JgOn1p57ky{A<8>3;YTcn)gi{lFQvz zxIuWN%z4jGT?c*PQL2cDj5O@+LzTZu#5;4Pr({On3EQ=AV~q}6R`Nw(9N3nc7=Fz$ zq(VoQZZjSz09R0$Co&=ga*j+3rr@P07oAW(Oxjr3F1fhA+~d1J(GjvdFLe?Nq19n0 z+YZ;XQlNJVvsKK^igxygK+eAcZD^>O? zUS=gh0Gas=<9ivP%Q%i&i674f!Er&D1)8+?+6rE}u`HMRX4fA?9SJgn5bre}{y1up~mTTw95NR{%B#=1tCV z5sfL=D%Ay4Pub{B6XVx%sw5HfisND%d@rIbWPrjr)i}^63zJ}sIM3W|NuJ917=R54 zr*s2rRs`HZ21LKz`ZJ^LFGNCnf#5*4v_Mf7 z7TfS}iHe)l-8E)PPQW+9Nq~UWC4dZy5D)ucaV9Zr=V|{Dcm6#Zz80HhMT~CG-BF>y z&s%KeaF}H`#SFsc8a9*_K@v8rT#lD;sXvU9HR92?+xNi*6jm z*DX5wg50jFFS=6j-=3jEuLBS=G20OpHr>^ct%fFEH2YgIG05Sc*$JsvBLUR#{Wiy+ zG)RO#6TcYF7e)W;XbrSJ5Xd*vb^g>ur0(^+!|#*_Cr_>sz}}kw;Pq9suN;B5j~F+# z#BqK90SH30xJ3!W;d9Ab`=f)4G>m>-pPa+hry#E>6Rlna27^I`X4=BP*1LQ4T#UST zKR;#28iKzWI^1+S`?&!SEXU`s>%Qgv*Q3${0(GRF;*Tp_4x(-Gaap774@;*br(r4F z4$qFh9EsZA#$CS;;NAHGBI{_o>s(*-R1^8gW1^-(QQhE77V1y5!(!d65)kJ0?Y^Y> zo=iTN`HU(7({l$kD?=deyloH~7m5Io&1jx{xd)x=Af2p0R>`t_`|%m|en&H;uT1w% zS?x@q=1bneGFDw%Q8FH&6}1UlI$qz~QWbu^eQnJtk4=e%=G>_&hZ#r{#K$zCWlUic zhtNoUZm<8F4GEFkSl+#Npf@p$!0Q!}*e2KQigs}HB}2e?n~&nu`SY#mv~R1eeuk|% zmCIBxALUzx$R)f2z3pSSAP2p7TMtsYqieXUI!m#ANKP z@b~VBT~&U)UADj%os1^k&GAMTEwG!Ac5@l)k^z6A=W3Yc*{R0K7tn9u@+RKoY`qx+ zvDPf$OdibAaNo+LUG3EQMkm;Y(m!;6t%kl|F?tv>oUQ5rPh$1|*2oD)=5oPnT=$mW ziQYGRbSU~VOhlBCaYaExKn-BlhC;i-vGD782uvT>T&&lL8SE?k`0yoB_qE3 zO;j+&j%r%D5EeYBS3T=1AIjhR@qmbWJ~|GGeMi6hs2WKv`dNbO#$M$jLS@Vwzj|`< zXgo;XAp(M{-Jg3jCOerhLPlwi;NT3IQ!9ZDO-A8%`v~EB3MIlS_yB)BU^uGQxwqKW zJU%wE@uile0ZafE>;_{9M^9>S10HG#LOgE_;IUZ|MS4|+;J=5*Be#p#wb9t z;h!IQX2NnR^yNcD z;;#$N4ukgpC@Jz+14w>}ovr>L+_?YQszR5hf~{&iRuBAz!>KwsXH15Ie!|g!XplZC zNA;?&Q&G?b=8!bOdTn=zzl!Xu{IHn)o#l64?GQv5nroBb))3>nGIY4Pbp?_j-Wt<%BLdf2ky=!q77?w`G6cD-ZHCIf7 z*&fE%&LwY7+oSe(T2Zdg81Vi|&Qa_7OJSJ4_tGse*QvA6f&u8_H;>R@lM=(A&2ZE- zfakn(E@o?@}87VD1n!U&npIJeJ; zMy!TNV9I^+ee}Hy@}9V~ZIJQl$4ZR47&ym9cZ)BK|e zx57PP4q=Wnw(+2*e6GrW*V`-sWGdW6kdDj(yKTQS5f?pSd$JXc+;p|yYmU6X_+O0# zlzoZmQ`VC&1-R~2*O+DO9pKj^X~MdvJY%)2*sfcK37PCS%ndafX-kSYF5u0!Cbu4^ zfH{2TX1OSOQbm#cb6_^e6n?dv7_-57&UGq`Dxa>mLlNMBXI7>xrye8Y>YVE7-H;J7 zE?^~`*%k_=-rGJA_k{w9d2u1Edp`sq0K-k4;fdJa_-1$6f9JEC`wcl7CP@Iwd6vdU zUc{&tbf^@x`5WjYtKA6j5joVQfC@Tv=t^Kv7|&|?YUWHpFeBLZ@A|-eAQo-Uz0CTX zPF6lXp7MUh7b7D->A<&)xn9gIzA_*nW;lO&+<5v4d1p8cfyu)c^Mo9nJ!#U3RvZ3W z?$zem(>Hlr!k#+|JYyX-JyruhOA7LcTyhPWCqCIJH)I+a`kJ$pR8Yq-BziA!icTK$ zpjt5lZN#j+bonRZX^EoH0hLbdW;L$PTpKId_vgCPY!~FnImKGdyQ6R8ByK-SRuk~L z5B$LRtX}Tz()qi!IOu_0{!JRz;nHol)}bw%R8k;bV{EqfD^NNdsRCO0Yco>7T3zb$ zyr<5!?rz0(VvP3R>VY=hRIH zMdS(>m`Bw}_J|bT_?jZ|OR@hoh*EbAv=E^jBU`2t6Jft&U7BGggf8%hZFsDBQb-EN zxGDRhcB09xV8FV(QwIpH7}^rL@7IiI&0~u*2)6Q^K8Hdh)jw>Uh!dM&PknTT`thNb zEo_X(8EL3IEb{xNKjZRYgBF-J4ED_F=n;b(Zh2lWtG>2B$PUC(t0Z2p2ZfkGZtXcZ zINtqro5AxxM>3_8JBC5Y7DP(w5dnLxdYJf`uE6JG7&^hEH;V$qYfq5?@XssmE;~6m z=zz5dU(1%s70Wvk)@DeXrPW}~CA!`=ql^&Zu4g|sx(We$hv_q7oWpcOo9qmFo!qFH~ngDMlN0DR>LYS`h1`a?LKQ!AX@QEiv%bXAX%Nc6>^D#D7v?O zfpgh6x>*i6W1R1X@SKZUr)X2|^Hf0Bn=Bm= zcIPSsJ+JUt1QcJqj?>uriOvRuL27&P106vE0`sc&H8nMjVaE>b8G8ERRuVVL5QNAl z1`KD{QcC=DWX!C+3X!wh;-_5>SryU7Ov}29;hX^rK!7pmtKNlFJ%FkugL_r-EW(_i zbAqcdIF0ze8IB|-3c2g#{5CkGgS-lnLBy5?_@JJ-Q@scAT+*`zw4B^q0opqu_l;J--ZY0i;>8Mj+G`&48T3e>Jao%$LbAqATtMFG{AoY;_6vRi?%H@xCU6Q1>@!Ot$<|9fapCJDN%a9 zq!jk`gry%SlW8mD>7`cfi^u|-ALxbCFS1`+Ny(9|>?`&~_}GdT>XOK@fQEX?d`@W+ zh+caQa{y-#I=?F0|f=Yzo zvBj>w#XIUN;NT$qr9LC5Hse!}&0Ok!dQg({Z?38RW=c%*UyRi26@vmis9Jj+2zVL@ zyIJBI4noxh8;GTdIYcU<_ho^D?XEJqsaRfXpR>QZS&YfB?PM;aXI0)|59~Vmsuet8 zPnE!-lMByfId-NI^4skhx^GitN#cHfLfR(W_xWEXXIaBLM`Zqv2siw+hPm+;pm2em zMi9mL_-NMee}7!pAh-a4UsZ_*vE+`9p<~<4>x-2C>-OqSz}1t< zM+?M8^hgpU-rEH+KwzdL8baI_xhuJ1EegJ?eLokQgZb=#!}pJ*t3XwHGCcYqM3}rR zv#xx1_`j%?#&TS%W04T@fR4wSUyz3d{_ofh`Xd&yiblk60XWd#p z=D*~DxJZbEwUjE5C4U*R!U0eG|KB21d63op7{uRozVg$Z_~qo$+P_np}yLs;r<#CQE zJ19Spe{~zIb&7xQ?cP>i^OyOP)R(Bi~w3_4`Gb@uCd_OiRiP54=ZQWQ?CP^kq^YlKXRD@hOA)?Sqd|5)V8urAG zC8hlaZy6oDWv9cn(cXL6f7*5}quCUy{zJZ+dmwn;?yVF;ONH_S{L%blnFDmQ7%0r= z4_-J+{5-VtVR%BbyCBzOD4sA!yII*69yFWh5JV`dld(?0sgwOY?_h>cZilKoHAGSI zXD=MSamaF8neDyZ`BFn8bzz&@aC8-5el*&3gma?Yy($c8Y_va3Tl04a(sA267~4%* z)l)JXl>`sbWdNLjgW_tk{r=y#<`T+V;qZ#-TRa>jFD(tn(e}Ia_K;&Fjw=7l0_BH; z2z+`|15oQ8)43;)ENp+Bqu!(*S=1Cq zFIXJBOr%dG4@~IS>tnv0qNQHenO~RfyK8$&gFAT}o|XdM1)dB-oY~eZ}AZ#tjpp`Z~|>yaqMx9fM-r zCrLQCU)E)zRekJKH?rNvNuycW{tho+_9jYHyn5Yy1Pz3(?ng|ts*Mx!ku|r~XEer! zL(kjE!9qcTq*L4f->1KgovFpYQF0m|p4{*Tbt3<({dADk`MCM0%yw3(3>>@BBv&@1 z1$YI3bQ`n!IsdLpq&`&WRl$*QLgJ#gMAF^t?o{IM6ZtVq{mL5Ap@h2Ubiy$K2*jv; zZ1Cb1HM<4yU--5xK$YcxLcaOwQ@gDwl(InJ7yV&|f`H(+HUL#GtVeJ2M1zfDGRQbY zU7_sT{>*L3ze6$H*wINh=(n_b?4AR3OMij=UQ0ufBGyzdDl^EhbK%`HuDNZR_^2=c zt21iO>J$#}r!G6Q0H3?tnBwN-%%l4iiHl-Qg$7#0V|3>$dEHZ|+sq=iZ$9ZTR}V)Y z?dGo$r~C5_IO2|tjTPDY%zyH1KkvRIMPr`z7T=sr{i%#K&ak3ul$@mZ zzeI)z8K9Es#Q$KS-jFl?L;TNcM1HxBrhRFeyoS2xoE!VD@fkG;3EA$8m%iw6^VFc| zqivhp(lSHJ*kx~aF!BxT0B1lyij|>P5NJSX=8(M{Nv(iuhW{B`IqWj;ffzA_uQ+~4 zh$`#59?-4kI_O>Jsb7L?5ZBVjc;j(3SsSy2J0~z(TxKj^abG2JABMeV&B%{%A-Aby zn{m>&V&1L(m_PDd^K1HJQ?6ImzrZ-fzfx?Ai47Y{WR#1? zQ@UqULZBZ}O|$`x)^=;yVggRqu8VsvXpqm3i4;-F1=V~e`IPbzCdrbRG3dz5>(v3B z-~#txbV}QaNndjN`Z;tPhfdxR)pX|0OC7{cW&u$QHMMTER3sXoy4C+iA>6gF%Y-+BWSO`e7jCmqSQI?AZW3LI;)+b_?D5WDh!8O@* z{t!Nc^g=*9tXoGZ7=)e+BgmT~`>vi&XUZUuqU?!XQ3JL|ZJe`vC=Iy_oJesV06mouy@VYmc}9pId`BYnG~s%w4@hE#*o{e?+XyOAAY*?;j-k%&-Vz#tdx; zv&t7uBGiAK$MDJD4^tSxujSSI35d6hVXUC5k0y2QjeAoo4UdNHPkt}WeDD_q3uBw~ zG+0mXN8{yySOQJ?3)nFcDjL*Ep7w_^c>$XZ^Tw_>vn6X@TQPV6_qTVekhA@%f`ES| z0X~1-=cOKx=W%Jo-5yVx{BFujPEvKICCQ^8xMH*$-4sl?AeQ@Q^ibVWy~7(H)kC;2 z%*44$5w>aynHx(L>{tlB{UPXC#6VPo$gx5L_~MtaUibU=Z$43p<)i@gHt);up{`PGNxWX!Cw9ZjJ+MD=fh(Ja<5VrWB z!&2pa`f!FQkbAZ`0zK*cs_)wfg|C&)GZ_4FgQM`9$n!EE;5?&7`)|}*((md1!te3+ z`5@Di|dRv=^>Nw%^ z(EZYK*i4!=_wFKn(S)$&FE6!mNY!SdJa_&lMVtxJO4#8yiLQb6*y5p4^nFu%k#w4| zEtz6P&s8+l`#|PwZCoM@EJc(`A;a`vyWbgNX7zA zf+R-2bomkDyXw#$00Gu>Qfx}k+BqnJsI-ltLlXN}8_0oxnlIexc`K5gpIzC@}- zv8l{ybAf^ajUC)me#?^q(k971DkBR#dbXG=0(>+K=ksq%Gw``+bpFTr;%CvVff9iL zlBJ(c)z)Wie7l={QE+MhStV8P^||9UAi72ha?;T8@7APYdMz>vfuLbJ&|Xkhomd2N zYE+?jqS&*vJI{PM7&bKIwU4Lh?G#J!LnDRIi1e(W@;1&;BOIEZ#$YNul`B3^XQX^2 zNpr6FIH6|#kfhcH=b94_zN>?o5~;ghqRRR*u!3r|j zwPt7ts;1&3SmNb=OJ!t4Ou@&3w*QuWrk^N!LP*dI%)yzx8ASDxd<({|&mR*#NGj3l z79z-j<9|v@4lL`_Y5?rdgj(YEWKf9bOTXia%T@Sk>(#r{j@S10^gS0x+jFfV!+53e z>nU=+mu6AYEVuKeu(^0r#|2zB#S+21@QIw3FE#n*c#^Vp_Wq`E(_Gy zZR2rfy?~=(gCXHdRr2rW#^qQO=N))N_1gBbWdHgU@FbCBiFAUrh;eBSr!`LBVn-o? z!T0o_!>gQEnFjE(mdXU7aN%VxoFF$+RJx?e{lqA8F5$p?K^_&s4C+o{P++(H?Q8m) z-3GC?vdXMu;)hcTv*gUKG@eHy6@jsH-_CFEy;vu7aR@+fhfpJ8V)BsWwkCyOe--t2 zrcv^LVyBnx05tApNFxAq{8OX-MEed?#ak~_)VOt(6?mn@eXo=0iE+C>KBi~nNY%Pn z*xEka%$ux^;RsK%c@$w@bXUprpT z;WsQQ$HZsv6UYfblN;TRyZ@AY@38dNkHCiFm=(SVa#tAptOq^r02-+`NfZ;hwG)(m z;X-bG2wdh0(;!FqUz;z|vMH?>54bo?V>lsue?4n59f`T+enva05=#nx`S}fryGy0w zSd$Mj;57mL;Vz(hWI2?U3QKZlc8kBidarvCA@9~U zBH9QxG^dsAyC*W40sW5_t*2l5cq9dM%64Mo%;!MEb;0h)x#R$H;+}<&Ic&p*{47hH zGq^Mc_64iUrSYRtAfS~ZRk&Z?R;|9Q-nElXIIOTC4gl;P%L!w>*dw5UAHQ0hzDr|6 z8AGr4WhK=zJSPwE$}SP8ud(IFr`-Ghxd8uxZwxBuM5x>LU;>EE^m|=16g|!JgY~#E zgsV!yT2v}dMXG6#*{)(F{t2`p@X0D2<{eKpS5yR7W!7G!I_|MJ#QHs;SafKasUq!d zNN7+?rrZWpFU~TjYoXLaWvBlIFV6JgRI!wmQYNLkxU`bjgR*#4^VFXg#xZashcOl` zHfClQ52u4M7QwwCMNWgpH9l>pZENpQv4UU~T<;EVGlEhmVgC)1T1*8g-$osO-3a(_ z1VtYt5)kP9PV;uQO@Iy)WrIuW|LzD^^J+J zYq9lZH?81g7(Fk!`PPp<@S6OxY~Ra<)N(@Z{(1&n7tpS`&ws+gdSp)-_Uw54OB!(g zS*l@=z+1fSfDQ;`(>~Htm0n3}pdc~HxZ*~ZOLq3>J^Zz#6PP?NL}T91i+&DJmjV)Q zpdLh*YAD>?#!S+8+h7)6Gav#G{=F9>#GN16YNBK)lm#j7x6vkzx_<2IXRR){%56e{ zk6~2_$uHx~-!`>A*Q`SB+S;(NyuVZTg=Ar#_07$N2B8xOJ%rk$(scrbG6>h{q)jK_ zt`oYXsAmuqJ%|a7PU+gv@mZTq)a$%+zWuf#C57SLs@E1=h6VE46lJ;ACQXQ~J>_D+ zQw|afj@wwY0moUXJxP8eI&B>Xvf;$^VC#lyDpn$1uiFbNW*KA<0Hhfyqs}YP|JQw7 zZn&@C^I_5f58!hK>Vp|zYC-l;w>b8K@h2fXkopAyLPS9+#Vv%$mdUUnE;8M^n z4TjiL4D-*#&+|a3&oRs4fx(}?r1BLjHlLKT75A9;g<~Wjq_qK2#(oo%QQ0(~Jv|&v zm;}5muRYw-K6TM@@^DH0+c)pNBAzb+2 z6r9~pY*<@C7;6c^PGf7a!(#{ZWn=!Grld;AM%x`!k4r;3>hs6NpKt}jC z!hEc)5?+;DXEKaJ@&tUm5S9~zkSKLgGx_;$QhM(swjxE4E}OK4eX{mv+2HGRA@xNH zN~^eLouf<}%VgvFIc(OePnJF4vgGo#FuYDZdlc+9G97r_=FgVxDY3)zYX|@;Xfu4E zK^mPKci~cxR$=)~AqK%?llRB=VvL-MbvPp;xsh=ilD~AL0mv)x@iWV@kqY82tdyXg z@&y+&`T@FA=@Z*ty@HvRBNa3%=a zPj)^s&rm|rvCDFxkIS`kWnl0_GH;}e=?|P)hB9^ z!IZ%s+BxJJqxm6KfOh!EDn|7W{VQ`v$yKTQ)Q~D_V2W}d*#m0b=-?>7#){iGLQl2? zgt)Y6^&bhr*u=!^Woieu6au0X1J*l8Qb!xT)QxRil*SJ2x2>|G(oa&nWI`LVD;HK- zCznC*KOY8B?;+&rRm{dDd_YO^HrNG+sK?>0cN5m~NfKgbC5D)qOFFMcXS)d_wtGPE z1M3#pymzeh<1+uLB9g6oPjFV|G16Gz@FZqQ&DtP~_Im+;>iyL6@9f1%HJD>}z&2n& zLbl>HU`BSO=j&H^kC|l;G{Kd{+x>JfIb^4`S`s7A%#mcUEwibO-;Cb9c6QP%S`T%m zBppSXV)GXe5I{nuG+=H)t7Yvs_Cf1vspgn}z&(grBcse7cE-&TBa>tnnEs=_h)-g5 zmgP!lo%nNa^f=R`BpQdaObvF|0G=BzlilPBg9^Jp9fcXbhgsn!fr{kl%E``aGmTFxH5;pUs8LI!4a zJ)NF01LkVtrKE-i-YbI&J@dvGd0EcFk>Dq{J0`O9N($Mp=kvGH#ZX-0eT#OzvRD$@ zgDBx0bHE>Os{}q+Lov7lt{#M3UA3$}?POH7z5E+hJ*jLty*z$-qI{*F(>+aBnNGC( zeJjC>O&yWB7mPCb9QqYiaR!qvjWZ)Ft8~^16N9f+Pg^zTO)Rtu!NncIu!sjlMeSeL zH&a+zILARw%eNhAo*SpHV-!W<+O1Z@cLRl`;!XGiR=gx;cYJ9$6g+J2+Lb=dBeC!U~P)_m=K>a0a?~HZ7+S-$3tQa+h_6Y9~#xp?7n(~&6xPlB->K+zrcd>z5PDtC8q76P1_G*_BF=`=89O zbs!KnZ1Bta?(1SlQT^@cjP4;>NKVa#6r8_O{k3?iK)s*yKWlBSg}03&8I3>qw8e@Y zoqMeWDSV)n^g;)4S5)3MH3KmOwG^^6(wK;yn2juBX{9b&Ivyu*sTO#2w)qON?vA;D zZ*BFQ^O@`ZGb2Jick!u{B0QW^(=N7n@(}ot+AXLh5yde4gUj@~2c$P77@52&=DY5~ z(nr|(j#wCxJJ_BJqeL*XF$?ON{yfAbaw z@^jVomh@VG)QN%qvY)TiDNz?1i`9#Y!g@FeQ9gh@JjD4On>SMvO0`6{e!qlI2-oh7 ztvRiE$!J#*d_Or(G7r)->zZbEvH5j2y$VOtCF>8sVdf*hvB$H-3@h|l3MF7e%s$D9 zwbL6v3M(n3R?7+^WxN}PHT2-OaK`mEDzMWD?hYIK{kvv}6UWq+5BD}R+kmTLOpH9K z4T^3LQzLBO0h%D|@k|(%n8C0{goaaYbG$?E1)?dkiSW2*u&*YC1(6w!%~qULduyvWpTND+#4ACA ze4*wS9w`(rookLvT3znE+hkgHPvMk%w^H zZ1)lR#az76_)8N<5sm+T-jK6qe?>3o`g&%9lZz`Zop;_&fRJ||>weBiMI|cW)iXe9 za5qT(0Tzfs-_^TKHPc(Q;B~t_W$LaX=?a!6f`{W|b1_@!nwr#O#F(59bRvWOYiu zx!f+$A>jjC{|%S1Xk@R@^A7-^Ugzsw2?{GI+8PoM+tbsVjB3T0>M3`$M*rxP68nmZ z-l{CULygZFyB=aj*Zww|hEetSL-AxSV4e2$g0}50Lp(qh*_?|vm0;f(-4Yh$64BgS zA|aofD44R5q3C_K`66v`yV|l#{t-R9ryn0xv5W*&82+0fcoMzGuG`RR?TTJt10U{~ zp~%fjv_vR8Vxf_=7n_8p6|-qbzqc%X{h55oW0M!ihy;0gm?emZ0M%T>}^)dP!nPrsv7DrR? zt@J=Ui@1LH)4$6JH8*EAKLFPwhz6wYnkP`cpqSGBQHY!i^HT<4A7?7aMX$sB7N|HI z@|93&*k1hM0_KF&g?EKp12_vqrGTi3z6G9r7l?OrqlW-c&lZ2^CDJ$tqqTlP6{q_^ ztQ+9@`t(4VJPqvxDBkx|I<9!{WdW)g62tK$`jd-cJS}Q-MbLUZ!pQwIMI4}12K&Tl zprT?@oiw2aPnr>$7JG}z&+Xl_5_-9v{n>!xG4V}|Cy$@9qPV`yi+Kry=PN5Kd9r9B zuhD9|)>d}>f&*^2%yOfn&{&Zh>A=E2?O`YhL3Rx;hle_|VE485upSPMK(Cz|j{ju2 z(c{H4WK++yCshQ=HfkFgfWVi&c9kM|^M$Bo2%S!D32TEkq<)3)OnyvTQ^6@GhJ zp0P9%>@Qchl^9%TrCw+KUAx zc3C?NY6})|*@l7yFNszF1jKxZ{D7-=zel)E=TGjBOKbeF%_8+MDqsR%JOP0KS65dw zT≦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

E0?R7?=k(<~0i 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

j&=El*Z>xsZ19`Bu$;_VjV?!KFDbxNl# z?9J^vkS|O%Cl3;xMDB3ZSz+e^anViw<*U1^pd@BSs4weFC`(JvZtgFHHrEAp@_e^t ze6AO4HIbNNPcl$B6ev8Os8PMObkT#^9mo3`rslVnqLlLc`$Q5{#Z@(O;>#LHgo`*` zpNl*O`OP2Cj@Fy`oZKt84?+mHs9)611(P=S-8-qpR@LhxtA_Y%K9*H$i3gvv!(njB zAUfd(_#sY_nCorFIX7{?|2A`HUx@~)o%5{0{J6Gub60l_T6;a%V~*+`yId=Tu*t6k zLcY8*gu->Lz4I8ca?D#k$W+;VHlh+FluaJn?`W*#)vH|dS*g@Wbkd+x2T5xRdk)2= zxRY2|mawV)Jr1euiNP3~g}X#F0gE8x3jJdPWu?0yn2vf&+Mq!5s&s)t$URnDoOmz5 zu#&aW!tH*i82|=aH}Dv-*a%SZvFg3EETgpMVstwUmBd~CQ{_F7ruaLc5gjeE$5GqnZLbv$p`~Weu!?7R2zw zp*I7A_Wne6X+X7K-Boys8F-W`0M39RG|!E2Jt<3Zwqg9nsEgN2@;nxtIb=ccspp*K z#DvMFpR#ig!RYN{7kqfA8wD8CAv4Xd>*yMm*Oz5MmJ zWynT#rq!7}(Rh6~c*a8^v-jea<-Laz`8PJk5|h=!m(#8M8&%VuNy_G4JTW%(RC?dL zpxAt#5cz4`4n~6n#rQavKTfY__-^AygJg;+59wkIu&@NxlQs;2N9WxGSFi8)(XH8X z`e_33Y?&FkSDzI=o!h)(m({=WPY8^|;e-ijV$FJkX2ux5sf8Hv=k5{EqMXmT)qsD^ zM+Fvy%Uf@T<7F9}2y*&1AGJkd;Wtlwr4-x#b}&2{>`dmH%jB@e_pWl>NmG=kR^p(d zjJfjwS^uyU+^{Wkw>xl&iIX*y(8Zyxwg2@IY#nZ|@{GTD{#-HqR~?Gk?>&Fyjfk_8 zwYC52py^Jmk0{&Q8_N_iCF#6X#M54A*rB z6Br;Q_O+nt$o;C7%ccsFdhP?ZT0zUf5J;@fDy)oi1dYxeK^^@bFjnKtdJwTS{JM|# zh3fHFQ+WHrXIY>%@C9=`kne4vefzef10z8ubc_y@5SV zCRM+a16oK1#UsrO16#9QZOW?j4*uxB1?+sM1A)y2_#?pCx(V3*H$uLHJxqP5q&>sQ ze@jc4dh_>|bF$hBocbvf6xYrHPx3>#Q-Q&2-QSSoMX{>YV4#vtJ(Dr6|R5VBW9OiI~4RHdlDca&UcE zAa4Y1Wwp6~{K<`{hYW;BW@XWRHuSnFE4#EGhVjcY1P_pPYoIyJcV9gE{pwug*M!$jyaao7k!z&oW6|H)sh(Wua<5CQ1Ee=>jYMe9+HsWLB%xWhJZ-9 zUXIc3DcA^T9CcF-{(Je3Y2}c3W~VT`c@8K{84v@p8x!V#($muul2xh0Jcz8?YkMaf z+pByXFnSTo;2#Eo0f8U0_hS>1f%5*VomtI=T{3P`9TZpYPUU4{+v zzVLVBqB^1(;i74kcp*UUvKD$X;^$7uj~~u;ku(hifR3T^_yzV(<}Kko2ltqe&t+f> z%ggqXit`)|GXt}hry74t9ZbBKB__hGkWwN_II4JF`5TXC=tadjnQy9IgSIzF46554?tho7;@(le3}=;+vJOl)oE6Ge~v^GBeZ!8j3V z?;AuFrzDPljugp_k2a^8wJe^IMzbJ}PS3bJKYEw}Mb#{5qB<0l7Lf!Bx9cKbs`txc zHJlibsRFvG;Lx~-lz3a6fkcXY=C2ZWA!R_fww41!Tjt#4Qw1z7ED{!<_zs|`ZJ#RM z{RhZ5ZhY0d+_L>@6YK*RvOmOz+K}nBYjcrmK4!C1<*h$rQVU)9mmdSd0M!lG8YI~- zCt(H@y&NA0hLlb=`2FYykos@_s=XC$QeB^N(Hw=9Qu4UR*4`MyGLq{E*L(@5wg|)B z#N!PdfgtDv>l^Hs?r?N;BoV1)}As|$^6V2o|$ ziK#tICzfS%Kl~bA{XRJftv3&_7_8awC<{~{aFUXSxDvi^4f|+c@1S|P1mh4VP*@6S zQ?D#d#;U!k9TkGKEiW$vqx$E3htatK>-5gA}e!FcJ zI`=46@^A%LNj>?VJ=j0k+I87V7%1FL*p{=ws{+0`5V2)jegKw0fSkyl@MUYlB&$dY zA`j6Oq5sm>)wR~w2Rh=LRv?~QTif83$_1gL1zzjPjP(Yvevx|O&0S04NkE^kpC4HP zVCu3I1F+Jc_IrkJ=gBhNbGd|M=*{+6@#mH_jsNlS`Jxn>9{ zrQjV%RVQu?Os49_ro5+zhK5#ON1XjrZ(LxB@Cs+KHIuz+(VCh@7+kc`3qM&Q(p2SD_J_Zy~#SUV-##@%=|05+J+S3w3>E|wG9 z(b<{vXypY+t9<(RDNqk#?Cl98a3=CZ(+b^+*At*76Yli4`BhWh#G`d-t<9pd30%K~ zXP3tPlX;ayvF+HP9QMw8wIo$J-#3$Ph#=2YAy^tB4^p}0QGCB_Q22|hrt;cl!6D*WW{u1A?GDTB3Qd_xxw5tMp1PLmq^P3}5CM&R3@rXE`w zDEdv*T;wpo{RI|24ZABsc&MKBkFI5(hh>&F*_iAL%HTl}myn1`n{|>P$Q*amnvO$F z^pvhWl+2VyP{G~whWx9In&gbTqz0I zQ87>g+cfq5qk#UHh7cH>xC6~Cs6wGWl^3&9BXkI?LhZR>l|bC7pC-=D&f#KeJ^Mkt zxAzg2xdTP2q5BfOzI+rmSMko*ad4{U!jr+fjX)Ec1bsig&cc$0MG^n|{*eyeive2~ z8b1+I09|a`VcZ~POoAaDWs{sfU94>}>2NqR=jF?nckXwXG&Gmz2>ewSiYkoO_L0N0 zi4n-`jEKMG&GbbGo5#o!%a%Yu$ce#eIdgZ;c+`%sulm#@@?ejjX%UBYL>M%?ZmkF0 z$j~CBdf_|+r|QiIYKV$S;-m^5uCL=?P|hA6l6RR0lv-gN?e#FROu#LLBEGA$FqlUI z`45v-ow{)On{-+wYVs)bI(z}b0h;>H5vSwls|nY_cKr+kKEqH{5ETKPS?XBmFT4w*5~Rkn7yWf#PFJi;EFn@AfWbjrun6us|wE9|$} zQoo8`4gq?rrHHLp4(i5O}Y>n5hdruas?aKF&9wF zRwM1jt~5DNP`^(f5Z^-6OXB34fg4zQAcp@9r5+7jaP;R-7w)Uhscjio(s4^ck->u5 z+gBch2aNkAfq>Qa1a z)?Wl{7ttUYZG9gLotI}uG=mUP-PFi}#l4L~IsHnH*V3?snO8HQroMGy>Fxl`+G+a` zk!Qk>ZIh>MxPbF!)e2<$t(X+U01CA8mo0}c)2G=~uFWDM%5w{+Kn@@R zk0kIj5K@{f*}1i<(L@t*6ylN)b>8l7HMlkDu!`}Y3@;NP6cOR!mb#BN$%k}AIF@v? z7NdCA_sfe;$!mXmk;$Dbz^-5nn=I$1rkK^QNK<3lVT~XFH>(Iocy+h-n{%P_HuWdP6XTal$9tcIBdm=ifw0uxDjzw{E%wZFahY!?z;da z*YYyKvMf$&B|EUuf{53c;=j0|M|?ImwSOw7uc78{nvv=f8k$eqKzO|}cG>;y(lQ4! z+nk-HA)jfIaX4o=P7N61!kmkIwLGdsyQvkX38UmtW}z@u#Re3U$cgMS|UT|#vs;G4m@Rz~2(6~TC^WyWg}@%Hx+ zA6A2HV9kLWO+Zktk4rwEd>!WL=H|BYHE;9ua337Ld=V#qLD*f3a`82Vc1m`ID2CaPWzJEK3TZ8(`y}sc>P_*t%Xt|i)c1X@v_J0eO ziKAtq%WFdz)LYx~iOpkgZcTuAqO|=F`}LcF+J>S>mJpb#y?UW^0`5dbAh;Y@R#8+( zB{bv|S8tupgTg+;UiIvN1&rCZR03E2^p!7l&QD%TkB>N+*-T2x0KSBzHkFbnrL+5uUETflk?BQ0j>l)` zW+xZ2Y2k_TWPZJ?Th6I69r=oPzX|BF3_N!y5uOc$jSvC)1yODyN^ovdqHp^^+Gsu= zXaq&FH!}tyP8vhTyaJO8f-_o}4ZwvLg|l9%f*|Zg;rO<%-qRYkzS>r*Cbb%9fCNui z0$0(e7sPKr?E2XB`XW1NlN+GZ-sYYD$*&c8Z$C4339MB%|2ywyDEeO>Z~PKfUr@gT z!}Mq}*2K<@9Q%g@Tjmtw=1v_j39PYhW1 z71!Ozi+nDr9S+RQc)3gcoK31V5`jJC5n2J~pfoLdTtfz$(}CY4ERk?cAp7R@W8CQgG8fqH$EeI98Y~q2sx%<6SWk zStvsXj-bs&xGwxx(eWNDjfS0C{j=@nL+uJ`9 zOk%;L@BwuizzzThAODrfBuxmY>1KZT6|w?G69U48C`$QzeCkj-y1pyGZramr*ro9U zgzHB9iQx-9CSAL$r$_e38urBnM~%Pwr0@=55yZUv4ypzY-lH#2J4{pSW~aLcv%wiZ z+?>5C+(9|vH1>sSI!I~-Y060zrIaFn9_dB4V|604ad#Cc9fYuvlS$G=cr25{#BA>) zrE8h@nSWjTzJJL%bRYqxEN|>lOX5#Epq$-?hQhS&!5&N9zTp)NWq{kf3gK^&gSDY6VubPvr{uOrXPJB z_qyEj3~@^b;8qD}l$BPJzIjta!ZpP4MiL9LVpOpA<)?}5j~>NbKsAJ4bRuXp$;rhs z-hWE7YRb|{yQHE&*>9#0m3UF~&u-!_P_S2gtgHlrse#D-e1CAVzjY&jMnn@^^=?BJ z9$B)m8Tt+mTl_O`nVJ3f;)TPR^|S5G=EKLfYw#wlwc9;q;BeZp`k?*Eo6-7;R|qqr zFx5rpZg}LEfEKZ({nMV6B6rhAgVpZSF2AHRvdF*kFok|YmIN2@c1jB=>Zd+Kfrrc8 z-4k3$pvNdHE0gW`b2GS=VbfCZ0TdgFhhrfkVRM7*bdZA4>gyPsz1b^|VsvRhqw3t| z`PQ-(wZCj%Oa!Dx!muGeiIgR`um>4TJ-8lToP{Nm9rSFOh^ z5N2%qMC=DftSaAiF5CfAqXc6xN3#UsZ2KV@_6xYe#|rZDdriI6a62q3u%tXUfOvyY z`*D9PG>(ZcM^$CLo|ozaPmZcy34l`?EN?v``|Rm%?2|+D5uCjE-sRicx6Q{TSm^+) z2k3}JUVxQll7YU#D*YoVFEL{Dr`kR<2e$v$0=P9=da~a6a=ZCY*9%$4j*d>=`ae%F zBmjE@f=ltt-q=u(iFhF7m`woeCWKCB0D#5h3nSC2RM2Nrd|?}Z`uYsQPgn>edwXnf zBUjby*VB7ffnE-br0&x44&hsj3!1-<9x=%kB9NM@c7Zx2#7+yvRyWkitS zB$Wiii0jjcsu!mJt|C>V6H!OqL<7Lk*0k;;_xiT|@!8Nl#ZSjkEgwJjaU`dGpQ_%^ z>K8&hE;phhX9J0RJxVQ&6{!N~e8xASn$b!IkDl5mQ#$aYsU4?=bfLH}NeIA7?O$?LlhNHwX&x7y}m6fhl zbCHWU_VlSM(-WNqO7dqgVIA5pq@m zn_LcbKDw#mk`lZS%g%m>G=d0}fq*xZvc@h7gHt2DXAB@YfyyaSDj)CR?k?TIziI5c z94z@HE4T5ftSOIc;FJawMr@p66fzNcg70&A2@GXIx)hnx@%iB(yNZ_$<6Mny0#L1r zP2R(kGYU@5VceJv%x54j_!>MG=)}PiJ@4!7{Rd{R|Eiky6ylTC-DWKwI3Jx=yWV3B zYjEW0^lq6Oe8bqq@H{6P%CP7|^q;56_9oQ;&hW^HUsjQKYNY>viXRRUv;5}b>5p$Y z3ddKC-DBl+2cymN0CQho{;_6*ny${lBJ3qcDytm?``816=u?axlptr-<>~1j*x009z)KAr%@5;lM9qU&)YmPP0UM$D z5@;5ehh$cNm4Y~|W)m+9g>Np4Hoa=3i?n$-U-)&sWZEm24qd6^c*C$H#t#>`KK)#xZ@X-JcC9`}SjG|7WDWXYEvW zr4%H6jG6-;RQrubatDMvhJ=*PZL%QD2k)d7&Vgxdc+)+Fj+6N~H7|?(Gy{(>-rTqE zK@VCE`#r110M!&2XG=z1FiT4#75tRjWBq3TtlMi&O72zP$&fSO`=lm`v|8cG!RY&G~W^ycfqtGdXN3xl+ONMh;zhxJN?D!h+- z*vx)Rcp1%H&D`c4kyb4~t1VgafbH$t0!2El0V4~;XFmLNUP=|8rEV#$B^<9dPFlLwPx5Z_1DT@Pi1#u1EP~I=e-q&N6!=%_18tGEbCwVM zUyqusx(7R$0~#2f&ZwtEV;46!;P+HcT32R7Jdr&cBYDz_0P()NSsc?KD_!j0zqE#Z z5ldWi+1byl+>g!Xj*QDqz;@#R5TI#=fVlHIr$0gmhAnH^o4WdX8erSpZC&$Lv^uiOz zpu%Yax=qb-)CFB~y2V98?j$&s>;S4`QStrg+vsiKq$*>?AKUVInkX=PhY<1Zq*r%~ z!AkMJ1e6QI&wv|A>(;o;jLcL4o&&m+p6BHd5FZos2vaZwX;T;b@A1OXPtH3pq>E6K zxO|gRaW!rm6}1Q;+YpXtWBYy3{93@7l^XTLEt5RDS|0t@uHqhpHqskN(6$e5?AkM`59kT${pAK5qfJTDA2LcC!CwYoYwk`(S zIzUCG9dzd&H}Ty&Ydsi-Y$)#ZN1DM(zVKro!K9_11HUQ9FT?FYLaTA<>oi}gFU=jF z`+`&Zmn(#;!rpd{jb-4OS+c#AZfdDE4D!kU`YI_o3zQ5(GEV->9tG$tSO-T2m3DRv z?jDSa@8fy%yzK!?rA!#qedAHRc7Y`JkB?GsjYgu#&p0su(LuKxJsXnrrZF2Vk`&N~aTh7KewWHX@^7T6Pcc`{oQq^^Wjk8=8I- z?s!T{ND!Rk|AhT`+hX?ekJUufz{qI!HroA~?xIUIo0jy_$4R$TN=rePAt{Ez*J?C_ zp)~?wZ)Kes*ZS4Y303j=brtn5epsAE1}2rWUe;$R!Lu?){Ei)9c-p0Yc^gQsmP9qKaKuxZgbbXuF{Y=iW@^b z5spt2n4O*$XS41Nf!BvMh4YfZWNCVO zdYo*Xi+5^Y|KKyql|_wl4lzM9qH*y|2Ffr&6oVf!90@;aPDjOtn@mn0Z8SbqWOvSr zRw?@C9PyLA4Qujg{Q>f`2*t<=nM-26lx}2tc!W64-PCdbB)I8;^I`aIF;{2#*h-pN zZ9rh4=gh|ogEzfU)$%C@+7d^mnH1cmGajB~o|katcZ-{9YscN>mjoVvC7;_Tq&la9 zLhM2m-$8hu$&Sx#`^a~vdWIech?1{`fos#pDpt^q=g&BkYBXtZ7YZ(7(U+omI^U1( zZN*YRDtzldY6!6;|75s!9rgey-H-(4#|s@D9XmU~f*Ab9uq!0zhLRF6r~%E~+o~gw zsj_pjJqVx~3&(Tk|01w}+?M;rtC`73F#D|VE3FuHlP{2Rkv9XnoyVyWyP5kLBqUVU7RuUU?&Fb3d@A zRzq5xQ00C#vsYI{X%+bv=y!P4yhCk6^Fh49eHI&_jf20YK{bvEJ!MJRiiwZ$mb7ji z3ikEA4{3#^p(1&RGahB0Zjq$TmBg3O%k-imbNlPNV5mJlW-MEkZ5%!~Xe%TWWtP!L z(WGgZEYzRtU-7BK+>p+csVsh=IIc{ z#U<%7s|(yW=DtxP>?b;mrNy_~475p66bWJ?WOV&U@ z0WMJrKVSIMutd-<&8~nHn<9rrLN+gANdt}Mphe!^OBY{fc=-ZECb29E;{=*#Tv$pR--zO!df z>FHXb2m*L^mg=fqpIb@Xx>a+9F^mye04Cc2@KdMf-!KdA-#DP#EDCnQ<0^*MPP2Ww zBee$4(%5AjRKvNF?5+o8r~P2$DFa5W`!zLwps(lr`!MjdqzF8JIBM>i=%w@`8yODV zJm`rMp9XL~*VL6Sk0nUfPq~3b$XGUo;Wvtur7&Gybt~D6YMQ74w;IV7blj|f8Om7X z(z)l9Hl_$IUYC+DTFHQE1fWfbqWY@$I8D?|h@n(3#L5tAPdf`pM`y-rY@ zo=S#2@+)a*P`F}o_69Bdt~)V4ULnDzio)N!I)c&vPn&pzMd%4h1K(6$2kHqHfW957 zoCp`0QT;hnS1G|V1alzUU;z=X#>Cm#dGE-)W{75Vilw@iMB?cvpE(#E9i@1x#sB09 zOFN@<3)+#omPmK5_DSVeSfqD-KWj^byt*G zG)smCDrpT$#N|m$j*Ug_-s|v05X}2lswVheREeCMgu-mZmnhT=r{6OVY3H;j&<+s4 zEsL|iWJ&vVaP-j&Mm#<_1;Jz>HJ}K|gK?IiHh}wvK5YNE5%_y=S3eX<1x{9J`I|Q- zB|V=lZW=Xhry|Qej(V2Mg4b3+9p}tOVtgtn3`dOm^k*vFk@l(u0+uh0Yu(y^?ky!* zB_v0Z+ZFn~O)E)ex|~hR21oGF~KHV=RQzi(#_HTrhs?6Z6u9>c-LOQLhN5H<_0V)oJ# z6>>|cW$W^1pxap>Aw@1>zIMPtL`1|xOpzJccOLnEVr|{fPkx@%ct>;Y{kkFl0gi=I z{wClm(dOdH1MsgZz8^$t;HQ_p=LCujWas6`(7J5Ul%>UQ)o+PaxBBiPO8}|+hlsE8 z7N({V!TOuhdGsjn_yn@aWtMR!+Exuwzr_i@C%1UBhEkP>a&5k5S&9Wz%&?=8@2~ zUZ4<%9xW)_!L?Da`>#|X;Ru3Y>edAh#6pQUuu!LkJSo zoNq#3NLc1jHgtm#;b+irGl;%741XAQ0#@fdg#;Za4Rg&({V>KyWe&|J7?%B2OtrkptNpigyBK%LeKnWP$(1ZW_wJD=`dX>?Gi=3Tr5^V9;|@#%+=r@Vq0SWX=daRUi2q22J-I~9vHi~Q z{BH1-{YQQNM8i80IxS?rZ`ooZBGe%)H$2nSmBv2L-l6BGoVj=A_+u!LR}@Cg=paD% z>tpjfcPTB9xtdt3mLyk{3LAY;S*Op}S9u_FPN?I>x$;Nj0I;AlxR&Lr?ZHA#G&Dh+ zx57kfO@7XgxKQ=(LaW!i9zjp3(y4>}eVP0{J}k>0?|LwpC_%_1v;^~2>d>R8w#P#G zzYmVISZgq@5rD@8q&HwFO_&=VzFA~TGQ4EUf|R?wX2^9tPM?h`=riC8cYqa@vZ*r2`#^t^A**`AMqu!Gcpd5F%S&Qlnfz2oB zf`NRa8}npZ(o@RI%23MRvS7y}*_VTt77-(jcvips9fxv-3BG>5DpIE^9H37<&F%u0pP!@ZC-?${)#-!ve%10? zDrhr&wTBgIRa7>fH!SSG-JhWvbQeYoCKS&trlr!+4KOxhf%_XaFH*$DJZbPQP__W9 zpuz8}nR%r}}F3HQSA>?#SDO8FgFDlErk z1#v95W%hvdNS;*n@_Y8QlOY6E#P+nz+`VQ(VM4*;+3vXnSA_&Bv8$s#krI$xr?Qz6 z7dP+#ZsJsXI)Go3W(nO1hJ z>+5rCo|ze+TJ~+&)8P63H7ZFi*2u^xe&FHI!(pdX0>Yk~BR`+}%9V}%!0aUgf{TMg zE9E$S_<&yh7lQ^hVfGkRt0J}lVeb%BGV80t2~f@6-iNSBT(yCvSKqeS%&GMoVXz49ARUeQIx8ge}`WtfcnGc{vY< z0o1v^R6`c&5BauOE&eT;9!uD&RG31@($eM4Zj7}7#a+r+jp$PCA*9-wra+a>W zd)f4wH@MK{wnpwCqW-B4o~LeC6#<4sc4QT%m&#xymX9Har8C zYyfK1*XNroU$rVGHcqO9yPMtNs27)g?s@WBpF~?g|4q&59MV znr?tUl}J1?4{o-STurf`J5PCd9a8P&3MDvZ?AJFkEB}M84vfE0Mc{Q{(P-!)BAqy1 z;WkyDDn)C4-4!fxtl0KX0i~-%Cwb@g#edpr8B(srT&@(X=UJ##2VO+=#2qUpi#^GI zdFkD&eY(|u#H^)(zTVZT9?ffxTKaiZ>N!?FCbq>Y2j6b4d)bTYs@XnyWar~UrK1N) z2_6vfR@VsHO81)H$v)UK?c2EvemW~YDFSv_f}<>NJWJ$3aM{4v#$I642LI&9nERVn zLLwRiltZTDL4e7}s7tfi)#|3F3qlY84JoNMGd4G0oD{0hf>Qo_%uNL$-Y{?{zmes1gu%<( zVRu7y_&fl~jc=2Hj(>73hMf29&1HJ-@vQ-AJC(X8rcVo8P{NsdcUv}%FGu!kkEfyg zeK_oV+i9tgns1h0M*yoHk+>$o*!49=i;NRwh{uolm{AQm@$VWC8^n=$eH^-WCf~h$ zWb%Tu2PU<1bkyrz6g*DY&@xdKFa`R0~%E3pw01XAC z1zb{1(?0u%PL<(@l{`wB4Dl!{30?&V%VEp&)N`K6wI9IqY=+S5ij)k1MHJLsywoPE zM0k|z_f_}Oea_FCm!YsQ2`DpD26|D6kNn1@2Ap7PIV#0`Wttf%0t2noE2}=Ba>R#r ze07*Gv@&TgrO$%A6lg+s{r>7e72anfvZDby;@EJVW}dclvs$FsUvu&Bu$R zfc^sB#4HpEgZl%8*cxj|`TprZ; zYH#Fqr`rz1w{&zUp^55-EO1iMKwiv28>9jEFylJ(Raym?V+NoA2TH&+^lR(tzQXQT zy7>4!(z+C_&lc^N>|4*nUjfLAGfklNcFl=MmJeNVwg8sV_oFN5P8l7^6LT|@M$h?Z z*&nc!e8gfp66BxUP1pr@=|Z=uYq50!GUY%-(^Vs3CyM#`!QWS;*>BCM+~^ecs{8j4^<62#dqkk zskhCtyw*sw`>#HBVq(K55cvYU;+vr2#i+~_lq@&dne;AFj8MP@G0VV9y)tSs1wx^U z;tAJY#m+jsARb^VoQMHip!AMU2e?51G4E{R?0802R+b`6`g%nvFhwJtCtV~I7a=0; zZgq`KPrF^Ozz~~0eZmoze;oaI5PDQ*#qv0_k`mgZb2n_a{*L`B3}nE05~8ck1~B?v zPJ2Io934HAK@CwC1}EoZgb@NlqMSB!0!;t-7%3@p;$K~joXqB-qHO#Wq=AY(>Q0y^ zdt!fh5q(PxOE_#mKm&LL*nDpD*ec|FHY}W2-m5=R4fV74v#|l2As}^bOrIRXk0Udp zAwbOoU|uLc?2fZ5ZDf-{G7G5MO4}WYa5G`JK%@H2MFuGNBbE|LXg$<(mdM$kr;*2C z|Gxs(IVT5ar^*41Aq`Wp^VCz#Rv401u{`rU>qK?DYe`$-T%~kGChWc z_L~I)3Y<-Y0%jNtYS2~=76fYC(Qy*kWSQQ?flOCa`OP>9Tomo@R*Mk3eUB&iMD@Vx zH;4HAKdpeT-RUY6_REP$b69*Y4m;5I?BBF_sPX4UTL~DzHQiurLo5G+AF#gtFfX^h zAE4ssE@L3kzW?rrs%Iqw9;&~f+mLk~k$fy~172=Ay51HKJ=Qs|MD0%bb@^meELtex z8sq8yzAqv9!#uU>&jcQ#&hniOSfxwgRk*5S24TuAkp(Oa5M~*IS_qOX+{&s71o5=a zm1LQhb-<))acXTSY0miQwpqZDb(?Cs)Zyu0lV)e*|8Z!!YJw=D1zJgyuN$Y4wMucU z;Hw1To6s|*k-T|0FC*>5gvo~`eSmb3R4>Z>y!FEYTOp%!<4y(yqE|93Jp2a?gCl>> z31dn!r#jxSRiKO5I?BO*3PDiY@gf_8Va?q9dK8L(71dtt;vIH93Vb2Aw9xoHK!pek zP7xGc^M`frTyQ{fNIZc*!aC{3_J*-K$so8El~!18Yo$oUk>@?FHs!oNdiAwQXbzR) zUS)>&Nl+hr8jK?Jtmqabe3Dqo*IvxN1?%u3;*7U52Sr*V;C-}l`^8*?GS&iVsu40XcG{e zJ{tUmSevkOiZ8T26e#3%BD_>QFVbBt0>G%buYTPx_Q~uy%8ANOW{+qac96-(z4v+i zrQL~O(SWhsLVTFX_C?T zoCv`%$=h_)prP>WCc`ycq~c;-cv!dumJueA^yRCE+`o45kl5q|@^9@IBHelLfWyu3 zrN8s#k?^0bt#erlH42R%?6y!OR`uNE?bUIwu`d^?tw@-*pXYP0kNV8X(b@pBxFU>E z`R`#07}9_#{iWv<<4+SSB!#uc#*+aL@0ESxXXd_a`G$(8P3R)i(7k}N(fB+lGrgN} z?NKXV>FDJ=_=mA-77lg|g*A}-_GE1aR4EWw)6dU0#bBPAUB0CuVi98%6}^Vi>KohM z9{iiSqYqo#*m$ShJm?@}I;xXm;0zi%aoauV3nCXUiWzstF0 zaQ2qnd|0d?~;&IYJUA>E_8#y?qbC|9kI6Ko4rAH@+9R!(^Vca*M}ZC0@$?4r{Dz zjQk}j!gyT^^!g-!`LF~gL;*+qK&{Wpe%W-O_{H>jxf-Rq=iTFB^ljiqdE>#mX%K>t zgtY@vQ0g%XXWD~_*rVcrOV$sktwW=n3OVM4C7f)s~bbtEU z>1x?qeCOjWJk|=nN_TqiN^m|YVctQJcf7h+?yZ#D8tqg%I-5WYX^XX3{T7C}6+>w*Z!3Knf zmfoeNwFEJbv(4tyQ4fi+8TaoXuJp@8PAzS|uP;H`H)!U;Tz-z{!&0T$-;acR)1EBI z+$%m=UpLRl*JtD5t`ck7X0T^;kCW6zJe0cSNJok66zO%D06t=HVd$-3yd*#x0lPGa zrrnbtzd>^x!z)iWJL5mcO%yg0>_?uI;iTc4{a#%0WbzRi=OdPjgCkmC{9mT0o05>w z@XT8TgJgl@z~d+uenBTe4x6e0EpBH535`R4H%kwEMxl=)ejqaNGep#1KwBRO5O!D7 zD>KUjhza5kQT|(V?aileo1eUxd?>}4@Qvz)mw7p;eIa3rXjMH9rW@rF!js$z-xhG7 z^GJsJY>689%(|^l_x!gui1-+A^EqwVD+?kia0dq+^a%^whn@w_3?e5_YnY`wtiC`N z-pRj@9+-V5Q}4CJlzx@^l9ON*3u{ODK>e=0Zq;(-9v zo={Z&bGzT(N)jetua4oO6=iL(Y)|F51su`eiN6`YF{wpbVVzuox4dGzM@fqBaT>p6 z&(RSk8I+5@hy2KA>ZE z&?AGSLXVT7pkX%J5>_pJ*Pfv#S6$=FEY9)Eh51YyuwOtet&)Zg!Z3aY`7c$#V7j z%>>_y%X{A54yppwGPX>DX52|k|8)-(8OYnij=+w+AeLot$CT1mk@s5u>jDlz8OFP| zEtpJa!kw9BP}sBNZzN_R@3q*|A97mx^0F8!vIQncU_;xETgrKuiR%o3EX165u|e_7 z-+ey_L^LTnQk8_BnjQyjKSG2ahsfi%cE)eta?Si(yp^@}*m-Kqy|lEnHrwy4W^|)kMYv@Y_h}Y!~IbPd+xo7e3`1v_u{J=L3g{S_1f95!1 zW9Obpz(mBw@j?;=nYdOFV6k|2M|v)8L9Xw=X}M!-y)S`9Dq((S$*3>$&c$}gTmi|q;`MqPYIPa?c1*F?#t)wrRHr0+I-vE?HjqS%c z+@f88tSZ8SaXjpR33YU-g<4GT}voB6r2qSZ`=><;RmSbg*7Hp;ZEns#b8dUp1}u$i>u|7L9d2*o%Y+$Gz|K zb@723z0z1?(|DDVL_e^$pDf_IdMha$cw)rOYu{Y|su;vbZv>!iA?+VnkYLg&oAEL& z%$MkE%YZOuOn|5pu6|5cVlCXSFb6L%h@<4udc7NqUHpa59rE1J=JP|s^}|L zT8iblp_@E&+~~d#Ag&S?AzAmzsJvy-b;0{-DT{3#sJnbRO9>Isy3Luu-c<1nEvE;D z-fJ#Ra^d4M?gCnwc5`K?f6g?MfAyqSw#~lB6d4u+*+JA6Zk>Kv+Dk$O;?jVGme&H~ zBDH4o%z@%9MkIelrG4MXW%gD+xxiCymb_Fn#?EnY%~x_r`1X%nG||?0(SJHIba!3? zT1?7dL!-u>NTm_sR4S$&b-rs($pSCWovYQnawi~Yc~E$)sIHC_i;RzV{3kPA53<3bfnFqC6j zVIw_7b|$G#d%%8gW3NrWz+N`&T-F?d|8iPBbq+d<1+v;{OGD`9yVE1(cF&5sy7Yo& z@zAYv1Ov8vWS9nkEVRvjTx|)Sb=dUKtN8Tk-+vLcLQq*#mkRm}%uhkTsb!#__=Rng znX_wmSGpdn{GKE+T%`4FNx8kxa_4$q4%R=r=E$4$QC0Z#+gFH9#ZC9RC&txvb?O{} zR!M)=EZrCD3N-I~4HfyjQ-A*ANlk_m6W()bH!*TigFE?e0ZPjX5ic_%TS|oK>iYp6 z(ZAz=X(?@s^ZZuVQCct!K{{ovWE;U1$LT%_0Az^_IUB&=dvV^YuiCE~v{M`I`a(XR z93Sv>OifSgW2jiXE&R;vgM&e{-}#5;{Q0iqm9L~7@Tq-gmXS4*Hy+yj)^acTefz4v zJKfg`M#N8?J~>@7NdPe~a;xkXAEDD^Az>7C4VN6}8v1XbBVmR2==MalUg7FD7QD)s zK#N2UPR-veG9u++XxFqMmaD4|frfYL7K!qEZNP;Tw~&;SSn0lUXox1ED5`vUx92r$ zaOd^@v!5-&Jp((#_nrhOF-vMdK6{zT(Y9nXpd$Fj#wNeSYikwdSJbw{@Xw_a&|M$K zGQGU4=iNQ;F(%p~@+HHz+mLa+y*e^sd=JAf|7g*$rgSe~VlJot?nZ+1 zf0(CL4T~LGU;ofajS1wG@Z{D)fGZHbBavRvvS)j{A_*za5f4uQ z0oX+{xkdG&BNAHg(Z>VE()Z?NG*;hSWK-loDrqmkbt{PvlWS$)u7 zu(bu3RvxD4G`sncs=B&?HQ%Gia63SYG_eemPFOzZ>tnjEK8*5F^kvDvciV*xbOwPy z#nZky_|wdCbTT^PUINSb;GlH|!BQfII!K#1{No1(77geOo54uU)s0KES}sx zx6Qh%qw)F#3|`Vql{2|58Om~$7bStB zK*c<7yGWI)5rgM%ja~Tq1x7<?NU}7$Gj59|43Wa4&M8#b*OeS(NK%jNJ_P%-0`9wm{?20B}@KLl!Hd(jBcEdjug;|>dePwFS%{F zEG^%Wjd4s7SbiqMyL+saX=|MJBz=T-Dl}PO7y}egw;K7SMzzn7pq>Jz#*9f;HfDyVg#F{kIEr!d9l# z)O}fZ{MP^d{m=ay@3kIio<>;VT1mX348Ar%Y%##hLUY`I?+)yLdPh&$`0?YjwI7d0 z_uw|87Qw?G424NTb|dC^4)v{fr(fSqS0LbRuzNL+kI}i`$tAyysa5!o zd7-&qkXEC}1*d>k&|CT`66>W=G*}Nk*{&+mBg-RlB3d_N(QyfQ^w)}p{)$rTfkkbq ziE4U&bZ5m=SFhu5UY>5baF@TP&msI{JC7W9goXXR#VA$q1Db=jGMuksiIY|g@sdA$ zGQrP8m^d)`1p*^fNg}&6@Se~Hf_ln%H~7OriYWFY3qhs;wtGvNq9S77i-%d6b8vGe zBdE8nQd6E;0im;l3*BhV?rN5pmwE7utv=jXkT}#>kzhpCLwk#i8a%nJs^iyHhk~EA zCr}r@Oy1c^th~1Kt)hIY0k_ujm_z%zS^+MCvO`@5&e#|hW-#b83Chz_hN@jNmDSBV zS+13i6d$b5T&y&OqTY8#Nk&UCR62;m-XLPxluUL$k@Ted*lgcOsSE9@Sq=K9n80%v z#ULtwrxCuoEK&=W$=AlK%~T~I{I)1~O=*N2Mdp$yN^lg|&IGi)-FPLpep}bs{m7r9 zYhJl>x^*R}zvJv&;mceKK(k4+3(UT9V|j7WFvG5n!ASB_@C^RB>Cr!zIO~pFSEJRq ztZsGvJW}5v<8TJ5f`{Ux3s6hBxw(Uu6lRJ>ilM(W5#Q*<&l=)>w%j7fxEg}Ywi?&jMj#aCN<q&*MJYGnO;?<>_|Y4<)Hz@NGp4t>@EG!>Ip; zhH5i#vVv5R35cf?{~tC+H1y)}TgB2RnU@u&7CdBX)8Oh#N|C)$kn6%KGZ5sd(aq5n3rVa1l%03SLVTl3p&EZLIlLY7a=Par$*R}GhT5(vJ_vaVN|``y zz;!LK2odcTt4~lteU+~fRnW5bE(V=;hk@u~0bp()bsomBsqX~@gNu|FhG=kS^lq%i zBx}Oe4o%q9B}j?lK2?u`N3xi zo{zt^WeP{8OZD~H?IqlyE4Kl}0t_+QM-vI3%koaH$1&{2Sl&$eQZD&KhTA{ei1rAg zfwD6hq5pV^2FZaB1Mjexa|-%TpgGaJgZdcsQ302HdZ$R=P5z`38SUFgh2={K+G_xb zAc2hn(2o1B&C~g2lFs_{mF^{9*WjAm5$PtkF3w)Ihs3U=+3^R0fW8DHSXzH$y2ur! zI2yQnxHVxBs?c2luG2xAEjlhW9;TyVE!(Z>3k!TuUteEw)5jp&bg(fMdc0OcNCNNV zTKU9^K2q;?7Tf;D$*GEM-nfesK0N8h1KxZ32C&OZQ`Rb)FpalwO=eEk{X7`t652RQ z425!lXX{PuM!wYH_+?@n2N= zzbvYASujn5i$(L+QBCuSYj?$}Q#*4+MWsY+3TV?DOLN7JPfbPseJX)NPgI1n+>E8z zegVzhrKi+E%wsK@g8p*NJS%L{I~(s03D`#!s+Vso+iv7wWbb6p{!D`VgIH-jZKoa0?vp-O2N(j;%kU8U;Jr7Oi{ z?#C7SgC!$s~npLeWLIuOeOT&e@ZqdJ1>Rwld&j)8$LW|H{8V#W4|S0520xC&V#L) z0as07B8eRhMSPrZ?0or5tXvbGmn_FQM0p1tSK?yfdC? zDydrelvqBn{_}iI;ls*vEAOR!o|%JJH*1?`UbM2%Saq#6HR&a`!o@GJ?ZuimzbdZ0KbyfVz$iXn5yE%&a3R8=;{?{he&Api>c{+z9% zZ@|g);$i`dR5#kjJB{F(xw^JigQ05(Z1BwddH$Y$Z9`>4V>wO2W zBJu?vv=#o8yCclgtRqaGO_w6mpgRdwU>tpi`O-vo1oB4uEdpDwq2Iy2o<59GO@DVf zaHH-+O!gm@7aMe186c@xWI)7_Y9FCf25$JcyZ6J|U}p>Bp#vKSYE9|C#z0msI@^%4&^p&ysV_FKSt9NrvHHMBKsYgX4-CA~ zTXFTB{X??=oL*d8dsm(SKW2q_`b-4{BBE(_z`SIDlYXJc{nX&AFjZYngXH!5z>OO} zART7jB0Q*`nPtbpaOXU2BseN9IsP^tgj~9zRWmW5aYL)Vp|YE!QZ!J8bLP|E@R1A? z_UxaI86zts(lF^Wv*HZcOhzTIt?^*rbH<-6rvB7)sRkKhOC-25+L9k{7yIGodhC+pcSfM1j0 zoR#78Ixc-YAWH=-G1*I5cLKo{*on~chOn?OY7yFKSY}c8bRpG9OiWyyzm}!rtBHGX zu%{X4HkPh!IDCt0Unvy-! zS}AC?E5{GNDxY~3PU)ldi{@LP|1=e5nVbHe)RZ+2O#di@J+g~l!q~t!)$TW{cfsv5 z^+ZIua7T9|5MtL*j;AK~On6k>UEK-B$<7UzRS?=TbMdk$XL?Jhd{&g#fcfi#C0>&h z_^wQW$wJpsM#SLwu9p=}l-?hIxAX`7b60WFeH?g~>_Z3z-+NjKGp~0?ck|$kcz7cH z$17tHmbv3ot4nV_8LAJ=kaE!6A6)zSU2VQN;|u^sR9Z>ibg{pV1g|$ z0^34h-&k4bi8C%wT5!yS_ZKY=9XZSA{yclip;aR2-|uqyMZWacKY2@T$y;$eV4StD zTDFWPVV&@t(lpX18r@iVEmrB23ba&ebvlxc)8Zyxx-?*N6`TplIMx6)W-Fn`E%=qc z%IFs|_w|>$I1)+die02Q?@`V$#?0(aOZ=+dc|gzl?@3#^O-DyZc>K@G(=B7E2V35J zGSTeA{o1P=Hng#qCzrju$9Wg-TBATmWDlFoye!M8h9IVDfYO(hpWyMeGyW9EaO1BB z`d0u@w&bSACO;4Ilh={9CC(+2bI2|bOO223m0n|mF6U*rl-PCTTs4ms!L_!3^|V9K23uxZKf_Ed6n;O+^feBGR8)nNA0Y#l&eCu(;8nzu7HB%$N;SUN

Y5GN1v{L6_9~dO0u*9vlkHn8Bp*g4=_MG?LH^isC8Ptb!=S;a>v+jl2wNr#v1z^c-7-t(5 z#7$lW)UtpUZDj7i_4}1AIqt^n6$D%|5}IuETMKMm!2WI>P)t|$D3xJ}9S^dVzD7yV zRt-?U*zi9&<-0!=5~^2ZSYZ8|UW>U>*9L3A8vLN3{w0(m;wXFJ{$(U^JCi+wC{^ov z5afBu?2W*Nz)q~YELWY*GFH07wk#D{Jt0bvX`+M+U%TjcS?W>$mjaq@nAiR)2jCnf zdnV_cd-~sX+jq8=2Ipps!B}I(#KfNV=}ndzmYJ|O2dr`0xw!g>-XAJrHvtUcB8F?^ z6e^au^W7=%ghBj?uA%%3SoKq~QQte}%&qyiw_;iRP8T{Xf{#}k_uahQ@5FbU>t2Ej ze!<0bYL`^NrOQa!I!h+MeU%%`3TWpIzVgSxpO^ z^Sac|$NKzL_O?>yE81MI4Q!?hRNqAmvrH;1q4A?+aIst;y87svg^=DzF{6CeYr2|J zOylXVuPKf})(pd8b7G*scr&mln^JOmo@x zDc1_6MaS;VVYnq_XakSDAECmzWAhHu7tBB690+(hH`%xHf5UkhLU$~zqIf3GVm=hg zlp)@Ih=0x7t?i%S88)fA|4lf1E=|I4d)v%t@?@A3(=GHp?fzEHG7VD-J z6$$@DyXRD4Ien5CiLo@Ahuc-?uK4)#ea7KP{+R2dw(5m7K*lcj`nye-W9i~AA)lTq zKln%SKQ92NX8^9>YXSte#Y{P?AZ3+FnYcW|l1tR8$zOn)VB0Ff8HF(Ip8!(3`)Z7p z9z&M(SEw+3wVfjYFYzVX2E{?>^r52u40a(n%657`Ki`h|tq@SzUa}M}$128g4xfaM zh6%MjIU85wjImMVZ3g<_ny&)rkzgE>xl1z=8To{S;gO#Q`XO$4zAI*Lf|8nbqU$(&uYaoCmaGZV|i{IX(M;G=yd+u#B~S zhB8N}2+2=fW>WdK+zRnlnDU$UFPs3Dpq8+3Q zltd)~x}lnEveMmh59*Xe2Vl40QR#5m_~wBZ5bBbWc6P(jNx zM^;4b!sU~| z>#7&|1`x33Ds7s^xJWVnk`YK-_G*DpqUonv(Prt*33)04{B;{JZ?CNvc-WIFULxaj*r zw-KtGhOc8$8t3&PU+q=j<&QB$IU%NzMj#J8ZnOk<_Ws#=GMRFR8KOBVG(^tpU}bsNXw8y1i2 zzB$N!*SiKyv%lq5Y3I@!N-;1xVu1?o(Y2XJ`wiertrR=cfm_{;`v)myR3Fmmh5PJY|4*-T~JV z;W(S!)X$A~;_xWKk7ZxEr7M&F_`2270QZP^UY8Y=|etFXAmy4Ax1eHd;A7JsoY@ziBJZ)~jS|NXrFP zVe43Yf!z1hWM9BiypdoyK51EB*Uc!H->Nk)0qx`*8@_>%pU0>Dp{Flz%>?0P5=)1R zQ&BWGL;vj6OKQAuQRI9`cA3z);8(iu-7tkA%5ugFT{=!DLp!dySyo+d{nC2^c4lqSL7PXc(Z%s+lkVvD{zLQ(fvrjH^pq@&_dAQ?kO0 zO4DB7dLJ;Zy4=t4+AO}T{N=aH#o3;^b7~h2g807_!vSyMsY7(g;stLlfp@)sJeZwU zZ-spWak_tSQCOb%jPK@Q?M23C*@^5$Ly$519U6#(qv}oso8m=vv0>S+sb5u$2CKNi zoOu4to*B`-qgX@`GidZ#v@po@Ctv17Lj4ba^Dm7&Q|xM?yX~G8X&A>nT7EpKMgQyA zJi+T=+rI$`0XyIWcwV@5P)Yz*PGiWfw? zC{_3v@qpMn>#^Cm5iAbK}Dpn1o_Ul z(Jv*kuiiC4r3=v8tOC+^-LM3qQ2x`L+;%WC;<#>+NxDu)D}xn<4L_JU`w2Kk(P&O6 z^i?otU4P2UJWp<_H(SqwmipEVOM2xMXlfx4TRCp_%L85y#1&f$Fd7A^p9;I0$qqY* z19$hlo z40x!)e{H(SZbHMEU!bOT!@u{*4nTjL{XIMCr)UDlMuKd zf}jt(6S8|40}kRG&hl9h2&ZSCH!uIT77mMc9X{2tmBe4m^Lg?@6r40<8dGE&xOtGVH2S|NZ_>wQ!q~ z$xff`R^=ix*fX@brNC(f^6vgWY`sdsxJ!?$?Pq(Rt-O#JpSw?Q&tvCYvREA7Nk55M zy2gwP{aWD?82B<98Pf1EzGsx_&u2WjQ_Dh4dGBT49cCzj@he*X+&)Xsrg2R4yA69} ztiny{FV!xqcMo-DmZZNLiZ7T!2vJhkQ@5#v* zmKo3UB%GtxbbH9DZpD2=mF3^b%!ygD!25?$j4XI@cT>>@gWk3y1zyJwE7l5_fW&XAHzd*?_`)sI_u9?DEEr+}|7!3ex>X`lpN&3L(o^41=PIOI0d2nxkdSNqo| zn}TOs+wWq}`k7>};w1Ph0H(oZ_g~RLZ~E1?s8-Kk@l4T?DIH~&r+S28;5|=~Q!0W% z!G{xkYH62!BqHx1dmq1T?`DVws^y%V*s)hqlB+ZdaS5H1wRv{9uGIp_$f7U6s|Yw0j9>!cX8AZ&373H(!DeGqUc0C<-L;9CKsZTtzjE_H_-HWJ|P z@2JQr2+W=3u146AvZfKR6?_tPCW%7f&>T^ zsyLRiW$7{z5=JY{8$U~!LN=P;lOFpjqC9M*f2gRjKvV7F>ditePA@L6RKv%1i81N= z@dVq-sbSDJqDQvf!R779Vgw0u6G}Pi(~y<0QV%@R(^pOhuF$ATa5LS*zghvL?TPBA zfjd`+6!};0Mn(g7s2nti^4I(WrIyaX+ZVH$zUUukdMR-x3<{i&{6++|;5@J1@ykM3v?Y(Ghz7_=0wB<_tQVJ^?)3^T5%jj%ZI)C=$Sn*e|dGetFpp z71jLK;n(>NObI;BTuv34(AC$s-+u1$DvD;IF+r5-k?`{7AtD} z&mSSw0XNqGlz)Au`3!&MO{D%}T6wcqG| zMmgeQa&OGZ;Rk+u*JoN*Im&RMUe9AFElDuyC`?7 z78Dk_&<@1a&%B8pndLG%7214uG(6~lDY5$3qbmUKZ~v)DZxoZOPoSu*1qGnS;8GZJ z5|Eq^|M>W*v+0vnc}VwzT2@6oF7N90tLy4J{?kA1zr6Rh_j;P&jjLRRk;a9$ie}bt zz0}cV%dYfVA8IMzea^++d`KbF?V6sj#&CpGDz`Ji>O+3}1cDR$Q{VxBO8Idg^o&cV zqV|L>{MW$F042mvoqU6Ulir^3(lvtsaO336#NBi@Jyy?=zbQiw#F)rj+#m!4O*hT% zfuV}t#4qXP^@M39KZb_4a;@pc@Z6}zS81H2YdyQ?v56daVpS zKt)eWV;{J8SF2q#;i@q;PbVXs0HUXxL9Q|x4$~&ls}MD)Jd6>_uW3m%EPl_jYki*; zg7_{2ZByh{n7vI?6l`S`E=fzv_#Ev}iE9KYo!P3$t=*1;pbk%Y`^^6qrNCh0OV(w3 zZfm&f!0SerpU>Ck$ajJ7BZ;(7XP%s&X4f*=c?phBSo!z*Y&+E6(Klq_-~H(`_U{3@(!&^g1>#8%yg6Kw}#%GdKb^LF!A4`BT^x#2`OR8=-b>( zAo+RVdtlmO_F$C2hV7LjQSf6*0Ef5lS;JHdqeanc9+kFIv&aFBF z)KX24vd6iHFsVgQ9Gie)^u)QfgI6acXV>tMI|3 zWH_k*9;Zg-xEfxqNPt10-=Po^i+|?ox(2qkz>j1lC$2;%5wAf7a5antin+h7{;#HM zj;j0r|7mI2wQSp7b}cR2ShiO;+pe44sx2%nFPqD@Zsza(`JVH;e|1jx+&5l$K3~u0 z1J0OQqVYbB9Stz!AE%X&pT%dWX~M!x6WOd`UVFrmDWm}IsT<MJSRve_=F zT3kC<3KKCt6Dlc%kYguVTNgQ8pgFp60+@!v!DM~|lgGQe@|Hlug^5pPkR!@xcD!mwY^vjKTT!PGAWD19j6mCXDW& z^<2Abw`NLzrK^X3j?8;4cgqzagqHH9snn|OBKwJkR`uV70XhuRU@LTF(UeYCDUc@oSc@??h7n;A4RE43n4uyk~(5uC3jD30)9a(`3OdLg= zI`;@D5g`QTMfC6zGR3CyC4u{fMXc?KX3=o3%pw}>H|}6(Ldi+9`hqK8XxBN@o5!vl zjp#=l(7W}}ilu=VN$2a}Wp+yU{vpv=wGy|}&csZt3!0UL9HV0Z5)}JoKzCw5V4Es; zlgk&FaNrC-_(h7|@t2-L)hvoFX8Kr8Qc7h`Sri$Z1R|9AzchA~FF{<1x{++N@NTJ8P+zzPzpKF!6$71po9`T z)=l$zQE$Kn2lR!tSsCzuWEfWgN)k=k!jmG>rKy89Ka++Q{Kyld9Dp7Mdu&9B!r*_3 zHn?G8cVife3?8Q(@SwTWzx~6Xuz!CY>qm0O!c(NtDlEm2&yCG}A)ZiCK}MH1jyuQ`%ii*D zhCC)%aqD*#q|aq&ehc;zr@9(u&=Z;7&2n@%4Y)WR;79jyKCZm>miT0(cxY{ zn3=qkxZyodZ}KIZho}WtBj?d*;YJ z@IrqB#vJIb+#FZem)YI{h4s$0P5{hQJ8LWE{Xi~{%|7Uo3p6T!b^y(4GT;1X+Gt5dRkuxti#NT=;O%Z}Cr68Oxdo*V`p{>~avcVZo{c8T z%p?5VQ7(K*X>^{MfNXQoZW`Fj8G?dIwmAj27M&4=l(wjzkuSk1817rFfCMVmeKe28df_o^scJOO^X3fRQ zqr%Li<|2`fszZ-^slnE={vbn;o4T9n0mPIB`nRgfL0N8KOC4rqGxG&hzX7r7@be z6f{(%sYdk!!T1Xs8m~4E;Zf}C09PoqB)xU_&h5mcQ(XGK2I->l90pMU-Zitswl(+3 z;2j7B98&lSp8g&A4Uq^=$sgG@h7ca&waajRM2!fg?)ox9-xOvMPeA>7-P5~O_lcVS z##v6}R+9e=f{plnb1I5IB~C*Ek;5b`GgKXxB8+|a0Z;jnoy*6{zGo=Es~{Ua;F`vn z>KDtihORToV{g%|=lY?_x^PQt(j@zi_m*%XhO5EQnl+MiF9d117yLI(Kr_IdSB+Z0MW%zgx=-lk(2DIe1016H1&x&L)|O*=~tpu-OEp zqhEjvSLNATqu56xvT~PO5gAe7CZ){}bLVuk@W{ugd$C@-n*MfNU=o!n)s@&Qz;SI` z8v{Od2H>l}T;B1mH#6G{69JNj`V1at$2{C{mZv2o&l=1hT=|1#o}r+iU{@QFRXO!4 zHRGmrv!TV0Djsv*3o)=pZ~e+AE7`0FxN`*Ze04b$paO?N@*_}Fp_VQN4<1AUMmpbs z%^qKNPO3XYMbqrZN7OvdzfnAgmFDR2G6|Ehcp*@D3i*zX;^oR}2|7k%s;O3ga$QNr zC%Y@u6><#VF%Kz%&-kW0ZeyK>Exq?e2P#<%<2xju#tNg=f%-{C_`@IT)UaH*lf;9t z;ez-1SxJ^q9X)pL`m|XFB5vZZA56JM)<93AsR4u*|V=z#~HK)GVHu zzD{}MzL^yMf@jxp@~sR_y=abY0E&Zd6NKh~A|T(ljzB<(cZ6W)Wh8ABV0J{giHiA_ zxlyL+>g*l{J{v4D+#U9AH94S_7EHdrG#gqg=t8(_Ke(T_m)tzezJ25r-Syhxvi2{l z+QgP+S2#+lf26Fbe?-X4VvQ&Loedc1I!;&WoJ!v{*xEP{@#gnBjkz@=^wgw0MiI~j zXeUamLINHog8QIF%zXyl4xftz!qe@KNQizHQ~9jw6;I|YDPuMtMq!cA)jk!!?}y#z z=U_~}VIUH~4%!SpfXn&ETY|Emvp#+7t-SBtxq&t&_btXLt)ZiC7*-DS?AgTpP8zTv zT;7yYOFWtNA^(%2*aiQjYV&@V7r)i@j$RH;amQbeeN`C2AniX%VtYJdd7ti*28<5( zuqOZk7v))cWc}JZ6LvKP4Fxqjs#r=`_+kt4!e4|5dGsh(`{AKI03wIHMXtb`g|w+} zcLc{FT_bgJ^2pGBJ*F9vA{TN2SfvKtl?UCuzbw8JNpBUrKNi4JWUv`O0Wgx?HLs0Y z0A>Ev+v(@Ux4@@R2ot59+R%9Q*cvBP;EFx%aB5gQ}{+K z;`x!K9qoWv%{m&30*+#CJ6D`_J^t)6eL#_0%3eA|eK2~Pj0JZ(h)>kG_v*9vSTnO@ zEVRhp3lzOh`VQIq+v1|Tw_9WqlJwm$B2~n@GFYabdj{PV?&XmH=_A|7%p%Dz64V-@ZNdm!x1^s^{0_?Wfu@3!EGj8-nNahCEOo+E~r$DLHc8SP6g#kQ5Cw2Jf(J{L@KMI zR5b;_G>bNjL$Dw#3?@Xw_~0QR6t}}IlK_nW$8jCL=Wvb|mS!0REdjoii_LwTz;LSV za8A_~)U#8h@fX{jmnh!hU;NHeGYf-sx+S2he+g$9@%<`lLNMNW0tB|91zo&4a~eY;CZUF!kaQJ_J-a-$0i1S)+dpo}EesAv% z+M8htdKn7p=*`BL0w6b8mPa|Gk0hk3Q(_qnYkPv5hv6mG=(P)i$k`_{E`T|BXUAUR~iQ zZ)tS;0859KQP`%*bq<0gvb~4~sdTd?rozveM?&-geo4ZYFT~d7?xxHcE%#|I&OV#K zN;;-vD$7v#=ZlI>KQtgD9Dly?;X;M{FMrQ&_9`2*h#i)WTIk)>1T z+EM8Lu>crl!xXaT5lY_&j+T1~${$L~^^FM>*hi2k)OJ1K5Uq)=l6L&#lduCN2+LzR z9hEo$#=K1IXQ6y+Jl({lXx*%QJX|(wT8dT^Zkky3LQ6f(8V&lP2sIgjx_j4BoB%(X z1>x8Aklh`BZ-3XI{;VoY$vb=+JeAvFRt5f@*$a@$uate1_(s&dcc%-*?i0ayp_8ux zWKillQtBm0iD8uL+mv>ta?$BKI>~1bqtrW(ySXWk2yPQfqPt2(ON~3;^2~zC))q8+ z^q2-v$(xijl;X@6>vbFchg~1nVPL4WyZ#|Wd?!6W`FHPCT~%FWPr(Et{qdvK#Hvc= z&t{|Hqp&lE!Y@Q0kX|Bp@*Qb@5)6~8WEi7f?pC-q8_Ql0fkLTP4ix9bj8-5_Fcc%W zsuYeMr3k?d9m@Y|;J_(Az|G3a3ec+r65*}jYL5o$;ph8qd8~5e?1xRoaB*rE`P)N* z{9x!aOvyCXMP`&(llhFwYH8|Lx$FO0eL&T)-FI&Us24B*QeDo@Q+`1}pw!B16HDrm@M z?F&=nAGPp1au8V@^fOr)S1_8F*##dHtL7h3!Fms!1EUPQ3o&*iq?S_nx1zx%n<&ML z<@Eg53YP&i92}yHQB@ck3tjjSH#;keVwwc&y{cW+L~~Ovw0q8vrP$l?1nL5Y$#8q^ z5M)B!R(}v$q&-^u_t4_07-KzIJj!qbjlX{TI-2{zcpzM4gp2~g^yhp;DTt3Ij>6P) zG*`WY2!T_<G29Xwa9_mY!F#&o6|hK z_Nu|bzlHKT-su!fRLYmON@f!gJc3>VIag2nCznj2u8~ieHtA z|6O#Do=#NICBTV5vH55o$r0ESNy+qr%gnwz;#*1F9&Ebo^93hfapI65_UCasx$U|Y zo)u6rb+Q85)}sF2UCT;Lj}?mO^kZFs<#Wf8(N>CVTkne^tGq<*Oldq;=A-wui973C zQ8xa3ur_sfq}(<7`(=>C`0<}_w#T#Fp9q(EI5}Mbz0j*GNg=Ou|NSfxfU!rzl5f^z zBd@3R4uSvbvqN@OOW~{7J^wb`w-5Gqiq?VSkkSB2R*&mWYG)5Ami8>oAS;vDFZ#V- zCXW1XULhJ3N9|dUOsD@)6Ro6~^7MmzJ=d>7p1PDz_joIDupqBl7g3vF+|yCxsD|`I zcBew8s#SCKACapUGkq|1gnO)7oU{ar2y9ofWtY}xe|9o!dgKFLZ@}7YEF&qUQ0*Ew zeLZg~zf92dQIT|4ZJo&r7JmZ^Q?b~I*loA~7 zs{I}U?QnM=v9WqPK65b|n4~pwY@LTwKH$nk8-E8Ujs3NgT~UEk(-dNzVEGDi1N8g%i2CE&gswmyu-hSAK@L?M*i>#RC9+w=`~@w4mfr$TJ!R?u)AE%2sr@-`Sr#3TjPQ)PW_ z?m6Y`X4;vdzt>Ne)ggr%XG?LFH(z&}YOkUqCLSM8)v-gVedD?X&-RlokL(!AXMLlW z7AF=pT377A(ufG7t&6CnP!=u?y1tbeB|@fYa$=_`9zLD+yeo>?VffiT^;JG4`+cTI znna~vM-V{lD3Zbq4h-$n`AGWOG2y|W3B$uttxgchk{eBBQ%+px^prrU8_#w__3N*( z(3Z5Cbd}Oii(pCJ%hdnGb}Gv~CnhF%XRX-H1zR?u!{(J@6?pzwy69wkPNZEhAkBRU zI%f;KVuLP(90a{j%LZMF;$A`~#k!rhzPlZF5<0rYuu_Ftm&&@}RfMbBjs#Sj(D zM{74>w0xCkIO=rtTV@H9e(5vMu+le28dMqSk)g7n2&5{ZTVP(W`VAW=)7ZLHGip=k z>@Bx14tAAJHFT%*Z0n8Vv5Hm>w70}MHm?n{m!AD(a)_7g`R&{JOevtkN}3gLS@>^Y zLZHBhDtnvvDNx&r3aZ+TV{Gd>=Jt$2t4_HrAb8@^EdKZ69@hqOW~VZy4lNZSWf( z!E*DnnR}Rf5Z;F;lL}533A6W4M>)tHBsD&XL@)e@>7QIhF7dTFA6zh>i7cNS2G7pJ zOwHWC=y@mOf${bFbz4*K>w7)Iq)cv{k$m81WN2_O0uU z`bKRP?x~0NRJ+<=ks_h3u6OztHGJ@3`VM9eH~R;;shQZQ1z8irj?Oh;3KWUw^bPhz zIF%2eORA%OJ{|V0i9}s&R|KPK6~>?mx2^Upe96whQafEf>Xcm$tiTie?;h+!(WPd% zt8xC;U)lB`=%z!T#H-rWb#-bU{xKNm{xwA#(07E8Htw;rno!-LI_>+Lbo8harxc@i z36rFen+@ZP2p8(JvtB(}7r0=QDn~WJv1R~+ymD~mHlNxkzneF+^QZDJwzwW%WnZ^j zTRg>)Te8Z8OnYF3EKKz~tAyV55fw~4NM$Su?f}lbj%t59#+2EnC+$23sO9I{^dio~ z%#P~qkp{`Nk-01(&q%c=6-N=&wiX9Em(=pBgWJWR`@(H`MCC~>dSn)ylW`BZp(h$E zDCXU uKr|4kLttB_#4Xx#;1jBBt8mJ~Y%%TL&yJgCxeS12%`Kg42^{9CZ8Iy#Ua zl$EB&AtfRq@tF9a2eipA#Dfa5ZqaYZ1Y94cz>*UJ4!%|t17nS2i}4NrP2F1p+ic$^ zy^G2#pPxyVmD9XYZMr1-*kn$DS&YrMHj5f0QiME5(Oy|OpH0jfh)s3=(WXk)9$8m! z6+;ol4Ys*Cy-flH0x+0Di&)6_#VPQbPd0%B_wO>7^?wY~?uToE6=vxhsaDKSGobB&K^>Hw!EgVCx3KRoYEZ`k z@c&z^M534LP=MRYFKz>KD+-GaoBJPz`S#D7uyWL5PBPi-yB;YPiRq>hyxAHEe{$H) zX%fZjj=9&@Y;C+hYVE=-j3K(H42y4p$He-!GZ43A^JKxg=}09>+{i+I#w4VrxFo&R zvo%^?d`H5Kd^DML?^G`CqO_3vDt{BmHEKhC1~5^p>sVe5@F1gJF*WSiE^!bBsV0{! zJ5*`l@-+R@o6H`Eu=g*Ri>Qzg91Lp}P|C++1mkEST$RZD`=w+~!Q#(^!@%S88H9XF zm^~p=*@ZV*I+3L5f#qjO?%u5tmbOAwc=hAfy^u_897ST6C!`tf)nP*TQ(S@;BNDCH z8=2VK<780a>k7{W7bel`?a5+1i5M#-tGuRR`lA)snf(pyL`MWnG`XFmB_Rm!-S@$n zN-+K7cSPwtL64d_o3P_+2*2`}Ke@IGTC~i}Uw=HS<_@ev!TE~f2z@4o9(*%)OuNVf zG(UY4J^uODGr-xkqKZH>Dd=O5R;AjvWgkrt%m;Ze?EgaDhl0(1Bt0}5(RTKayq#H& zO$RI54>*{9RjmGe z)KQLH7M@6kCGaJ~sN?X4x|Qc;!@^a_6`B+0Q8vL*NZertgKjJz7sa{XHRL>_$*RI%=>AY_K<8CyX=hGi*Thbo zAn99_JBgeNv+|wsdW#_L)4G;09=j!usUe1yXhdAH;!xPhVjvD9utuSzU82d01Kf-sjDz73>!POYpF z<*%Tqq2*A2u%hxH{=JCU3Sxz`JiT~GM!*ii$b2k}#;uiCFPr9Yq(=OFJlk<2h@`Yhm+kx9l-cE_aBQ;TY)DV?o^Wc4pv4MZ(wPLxCUKcA4HntmU_64ZduoauR zKjG`DU@hhzhPInQv^}|2P+%59pChMgN37ZZa)5C3;ld3~o)DW{r^SO6(gz)VCF@A% z$nq7IEIP%vjNa0;_ROJB?NXb)m|9!rv*f$!{Ys_pn_vn(YB3?G6;qMXevsFz#nF=x z+d1a`k?;7-;!4-qFSb9uTY()|(z=Cv-Seg*j*B(BDY%mm`V*fp)hY;imq#kyo=>VUa!`QV5P7>q?B6Pq6Zd)MC*ie={nHWP zam~!tq&8Z*@O?!#-DiP9d@UkD-r;tM@xey=2~7VA3v#Ps#Zi&2(44ZN&SAzWW=zl% zT>LM6dA(B!?-f%g>vbX(rHGMk0mG2keOH z!Z#Hddf%NDcYh^?-nrhplqtr-7h{-U1*0WlwxQNaPB|?t`?K=@aySytMrXKsJ+ePe zoT3$}sq3PBavrSBwl%VJkJzJri>yz)B!b$T=qyt-KOf9lD)eQxlLh-NAy-JEIFTk% zFyq?3M&~KYJ6s3J*|q2`^S*rJean>u>5mkDdOZHLRYO19sfk>S2p#JYJ zV8u-#EAft(ybhVmzdfttc^+EKOQ@nZQ&togqT1yOMPGa?@C+3X_LNW#jukxh5eqDG z&WyONYO3ko|NZ%2;Ff(Ko*5fEmf>1!_JrU?|EeVu1rwfnY8Fx;QXm7*qXC}fE}hr< zmi}q|nJDZV)hH)db+JJ+n&>}yr3gl36~o%s{|)}@9jj(JQT*nKNSEO+)H3OswgC^O z@;_E?S1WU=f@_{PDb!Kg+kAFkbz@#!CMa&QD`oLdFpsI7#M10LkgAP*Ds)ogW+%r zJ=kD+DT-hu1{hF{ey_$v^Qz|!m4wvo5BkM$Rx#CzIHSk3k}M}CMVS7&I3ncPd)gpS z_(g~&vh9woEqOq++Run$!(ye;jZ4J*kw4gXFTawFVv{l9A{Z9FB zZIWp?sEwaQ>LtHkHdNqH664G87USH>u!G-wA)$W3sXB%d zpC5BwlZ{2OzUuT_&E3&(S3#ox%yZa$cr`nxas&H^Mg=@!Tkoa$IhOFm{$?*t{(FV# zr3}+%?wtcSAHh&+$s_c2=y{Edq>w2?ib!uwL7${i*)W9R){{b#r zz}St|J{wV#sXPe30{GB9ruvR-%jL1xEU)#zgK@V5_yS)$U*BvzeZ{-ExAo}B%S-gY z%f3Y;KbG;CtgQci3y=n-bbX#U+svQ13b_$4wLv5bh->M-zXM23xo#~^Yl6Nvhxgs@ zp#Xe!BeToJ-*jsj{lA{8K)WfyLumfHo-!2}xdVuCVLw-}|onJ8&pMy|S`p-fVCF97a67k5ox_ zH^8iVga9}sbd(#_jZ9JC`t288T!MmvJUq96-`o3uu|MDdW z6>z>9Pa*^eHo81qCIQdy=WX$DUaK!;7%KGi{+tlxe{{V!;O};!>kkhP|4nJb`@F3W z;1rUTl*?@g2OWc=*3l=a52V1t> zj&Ff6LKo!^db&9RY`^Z%QC?o~#eyD7GXS$kKz!2sCs6>UDzD&#z`<$;aIys)qW9Cj z8W9qa0zASo-~{aCb-L4{9;qylPBydg+y1(c?xi}F6rlQ#EQBJ|zO+iF>#2{MiZR%K5vmfcUtF77g zM&R>5>>*VYG}L^-+b2Mhn|(^`ayy0&Fra#C0+6K_>z$Lrkk}t|391wlfUEq=NqwNl z%R|%_c#ErCHRxel78Vv(*2ueuCm9%R;M?up_4TrZHPMq%k&}S95^(oE*QF@{bhp#+lm%Rcm3W@#|TZF0?d@Z`B6P?lKc_+kDn zFwoT0^!?3g?RS8mi)jOX%cIJ}>3XOAWd7RgE9|(Hn}xSG;O2LKz6J~X`q{@SAuJ&( zGBS%NXMA|L+RyW%%j+WF?byH-xWCHEO6!7v=K5(q0fEQ)ffxjI;=}QgVqE{b)pjpF z`Q)yyuHebT!^8gmen7LdqqTLZDariordY*ktxE)O*Af*C1QbSPW-yWf{A@V)j4xd{ ziVp^`=yP+k{jDyzfa8wFd_T?XEFWDtEjlqjyU_FIWcTx0NJt1Uaq?M^0n4a*T_4Jin8KBn5JtA|kto!L*q%+x;7BF);RjElgwYB<9<~w!YE(`(ZML=!}%T?Vk zHXMrIgRT4J`T=|etd&I|y>KHwz=Eugy^pd5asZ=rJ<4`J*Q_;wP{o!nEFk)JS|50O z!mK#nK?ptGc={&Qi+8ILjFN>FU)*_p@QPV$1wGAuqKhYa--b+DpKplWuAJ0&KCJ-r zcp<0s85#u@wevRb0@!4C+78|v&U->1+uAe$iPV?FX(sFpleu%G%R^NE^r=aMk^=mM zf`{YYjG)IpGS;zi0TW=&G?)!PjZU(F#D+HB_kO0tF4IFb5u{sJ`*LTx|o8qw$xnfakXhGSS~2 zkg`PZp|+(+#Scd0S{25Nq7H&lCQt(9ySZ}gi)p%!M;`l;#k0t6m$dmYf}2~*#VR2n z*hfb8zMG=TYTTC0O*Baocpk$h`hGgATB|M&t@Z_XSFGk*@1T5}F$&p` z?g&w>0iNOmC-4y#<`(9653oB1jJyyA2U!8>v7_w)ri}X2e=YX_2?Jo?6{tD8rA%KxIGX~HIg}9!}{eq5##eT1+ zK6Zbglk9JxYGPv&X`B{5irBo|oCVTdcD~xiOatGKl7cZtM47degyWNvN($ zh!qwA?t`D3-{p2>uQ~;=2sbwD;P-<}fVb8PHagpWw0fIA(T?9&OCrKb#4PDk9!w36 z+CQy>`|Y9}wb&XMZ(z1n6Jmi63M!gWr$0bVs5VDHQ!?myn9ndi57^IYXlRJRXA8VL zDvw3RsPg6h+7!ev8UR*)Gl|<9%s!q1Yy|uIs3avr0iTyP-@W6drI4to7;NA+fV`(} ztsTf({@bL-p7B^%(=qg}x{9~XG8}Y$;Vu_Gl~=R=F(c3pMoQV{lWUHqi+HFan%Fbg z2B#Z)e5|+7tm^RyhDlX9Ia*moJY6z|g>iPwy;-}I8v5l$!Gnyn(L+cLrD&jcj(cnu z{hhVXkC!k4e7;&MnXJ==ZLaQ z;9F{+MveH^I@}0CD?$J2i7#_xl_gvipHKVU5i- z?&w*>-vV4xY+D--iUuO?-z9}VU^m#PRMY+H;)@y!v5QJj>#nC9wESPEN)^iEqSsKN zj&x8P6uFA)?$4;5N+mS4)(AV>0kDfS#?!Nc0a9_Iz2^P~Ux}tW8-3%O|fd z#sQB`pY?BB;-645+Uh-)H-tv{>SXeR6;~0OwcC*tjmeji&X7OXv3$I~VcPH_FC;%j zqcy7nQE$NKA^wx*61=`8>WCZXkFxoC^Fyz$7{`uT$gu^(vzx0#GejTJ1q3f5w4A-x z+VZ0|sxF6k@gc1tjpJ`LFUEp&WQ8*-QwTt&Kdmdta~?HEq(Fa}*i%Ry1bOD)Q` z&fIG)zv$t7kFRg!VT@Ar6gDGSwwF#Rp4V6>EGRl(>pQf5ZK3~mSle*g!1j@IGd)Q> ztdJsm+W&H4sF@AN@R>(D3dUZl#eM*${}=_n2L07xwe$DGZF1Q^c`i&|UX(0$q;>mjb-5B8Tnh|w^{FqcPV_WAvI8;-s?Yt_!3)Cvqili8FL^36!QjHTP-nPr{X)`9=zQX5M!X!HSoEutBj$3{#o%=ZTkVjcGSN0h@l7}RF zgybVkie`yvNg=~N4$_onFdh+kIj3zb$Rc>(>XX~A9b|P&sUlYyH*J)ha3V1t7 z`SNT`39VtGK|3d23Hr+-TGWa!R)3_XRdow(Xkn_bLpiyu$(ImH6v%9_+;`DJB1=L7 zqRl^P-ExP*YLy(xX~x^oOK2f?Oi4)?eHiv0%t~RBRw_&mW{{c_z{DzyL>hm7pl)-+ z++!sxqK0KQ;^sXG`GJ*yv#1dk#LnJ|7#yoxm8DLSq6sY{w1k{cBQH5m2r?tW;h{h^ zF+;_rlA^DSHh2I2%g?z|M-zTWZCJ*jfs2+_RHNyy+hboO;&-y}2_89F+ZjZ8sj+?> zWVb3>ciI?adc^|doi;jgy>*=LA@zOQOko85OxTfF$seu}B-Y;H?0RxyoQ(_xy+ZGq zDpuh~6F#VM%SS8I>G;}JuS3v;K2vLmOUbi$2_?gG%$uasrNLBfomD_Zb7vRgWcTMw zh5X@mXJwzU306OZ+nNNk6;y>zX-!!5LXu&`hdt>M5kxAAf@he&{_G(aWanhv% zQSlq4RE0_q;-2Pa+9qCV*c_Yk`25hQJ~pA;Qr<&jZyl2|HC+!6#T=YN>TDyQ>S&w# zK9nO^8VMs)j3^aDN(sisvjHV(>!D$Mw2re1QG-q_igq@_Yr%mY2t~z}V8IS0kp2*r zkxKa;P6k)2iku2}rI1;oaE9Hs3QD{6r!B3fcL>F29qAwWQc{}(l0;IH{h>HtX;q180wWFJWog(Ryf#%i1njVwsMI?Pmu8iq)tVft6i2bFsnL_LrL^h2=G*V zVD#C{vHRT0>9g+_sl>blz(bn4#jVor32xtRoh06Tcms+ zU~oN3j43~Vn(()nq?Y7?bUo@*M@DgBTS3&q}J61}C5lz7dN zqW7H3kuB@V^Vk*42mgh+)XpMB0cbMF&Cuq?6dSyY`ZEaOO*8X(2mMe2P3wKPp*3nH zGFL$O{VJGj_6bLcNNOXd-ae>Zt=yOcw{~Y_m9{ zQBtC=F!mW-d~q>!v3tn;aB+clGVM6M5ZPV`Ov_Vyn2r+kb~gYqR$;xq6f<|oD1 za+sTFq{Jwk&tY^pz)R$x~+;ybDdKwLC!y?T3+d40+!N5F9_$Q6NHxaq_cX-G%CPUD* zw=!-g)nn*&`Py)3@$5}!DB%oCb@AU=n|?XsBHK_xIk*j>JBk$kSM-q2=kaIv$)4v> zK@bW)W-FbA=WXs+A$N=6TZ^BstSu&s+jMv>eCT9?u*rGMdZK|pt{KcCUZ-k?g@BA+ zGjs4qll|{?dMWhhZ&(vK^ruJcZRcL?SZKZD7Z9+UZ>%dUywq#2Tb0D=N&fYDZ#wW9 zNv5@^%igak)fBkHx{Ch6@wd^x!Q!7}1SvU~*=B1UOqG?DwY0Pjrfg;mya%r*Cr@^! zN=pk13ri)GWyufX6BFm{+i@aSNQjAT{+7{MYlLX)>3Ou{2tZ8P2M6;daK5slQ4r*e z7IJ6dkoWbElG-2Y7#-FDPY{o0LZVw~@%r`Pa!^pE^}EtcE@Nr)H5*W>xM$Z9QMcHz zjI1nrz}Q&qPD#U1Me){nfm*sYkLPvOn*!CdPZ#(MIEL^l*ORkqb2Mq-B+oWDCnng$ z%N{_qM#AiRwVRm@2hAgs{D|o);HyYs=kGNRjUWGfgm(T849{0Xdfne%0nfiLQPxr; zUI$!5SVZK<`hbwfWk~$*)1vI750bq8!PyQh=z_H2u_5@}l(-5If+?J{p}=V##xgcm zO59*+<8U2Gonmc>Nsn~4Is>6IrND>j^CNx4iEt!Qcqb$#Wat|#&uiA?9UsNlP7^sf zxxm0c3=E7;qL;+P#71FF5!mf9Fexcxws-hn<>_Or7zn@0=Tz@qI%gFdVs<+~Vqkm} z&Xh@X<7dM*@sOEn`WP4kWjR|KGvY0)FE7u!z^t>(J!w(P`U{>~E<$dq&J|EusZPbbnUvj1bgS6yDD!=o4DXF#?`e1iAH8rnSO+kW4$9TOts}MH>;>VPn#7?2 zC|Lys8@~ge9o0@HK^4$>Er+fr3hwRK`rZPA!_Llb*V43tDRH?}=Y&(lpW9iyBVgz~ zrSI}qOY0fk`QFUM-<7BX&x0oHG*5@Yhf@l9tQM$A+$~T33_Zfdci5`PGra55VoFTZu4WH3il8%* zk!kn$zBPLDCdZ4DGSXv>)zH9u?^mH#9tb1}y_!(Vyk2ePdgT7Zsx_FK9rUX$l-oK2mBG6MxL)6>N|mBPZpN=i!7+0h%WMb1A8 z3;$NElwa|od6yxp)~RH=X5-DwOj9GR$Rnw^aQcL(uB$9 zJb%MtGXuoI%WqbE6rr+i^$l;j(==0s5!*6&Vw$?T?&~UZG4u*ARnzTP64{;B2j-ja z7>E3qFzxEr)=RzbUgYKF-CP_TY;HELr=IPU7}PjzG_bP|J~bsGWq*J9)6Ua+YmBj5 zjZ(tv_KVKH)feKQ+Kc=8k__BJPX?sGDC{%$ze(>;E0K2*<})|vdre=CmXFt1fmVl!RHDZiw|c4}WA6OVd=-)6f{*wp6TT5-$WOp8v9?c8XN!f<*~%l7vl z{C4xRqyHR?7VeFnrh{yo&L&Ge_pFJSR0Zu9B`qyC>YaDqmFiUP%(>|5zDH}X&B|I# zTexiy*{^NNUYZ5Y)8F53SHG37&U|_`bDPWG`M&WEDK^99 z@LN{)Z#81()s)`2ef3hS@7=T!<2QN*Tp9^4kG^=Qxp|zS>so?bIEnM;&%4vVbYZ?d zAQX^@i16ow`SFQ~DzCe1;OOegUt@iDdw*fa_v#hhx6GZ`Z|w@WEkHbr%uoA<*fkz? zjWH@uPfxq-O*7_U6RUQ2M(Q`X{5165n<#o?TCQzsy7E2Y$GpeM1(3trM5I{j>+695 zj{YVh<%(4F?A&r#F*q7jy0h zv5d;p-nZokUKb4+8T!wkzq!9Zcrc!OHN~c1e|pj4EraI_%h@C@ zsQzN!{b3`i<+fMNWBG^SP3mWSGwg$w2l`5jLAOm2Jh7{exT7y>u2=EF%_k#WUta(V z^?E(6<=}1$K!gRa8!8%)!#1s!>p%1gk;0LlCxZgsCus|fH~S4Wb_>+S)UVS8W4O;3 zfQ&Jr=FO7FkeA#U5S`cwLU~FYvm%@qr=*rHc(lgpUH9|npnw-am8D!43m1Vab<08X zV^X-@%y~HCd^j$He_Zmzc(_!1xZG0nbi1iWoSmJ4V6t*@7&PvSD0G)e&8J!ijd%RC zw{1-qUTgh^UW>j_cY6!>uetbv1e=KSqQvw3-$wJ?<&`!fwSm6b%`5MX|pypQ9MYzB>Ax+AH8$d<)>C*TV(Kd#I1${g2XS3N{G^)AG)6 z(w4JzUAM~pk!+b@JQ|%QH)lSIz1>|tF>5Q2*dt$lKJgIAhVApyPu)$m)MWMb4a-Mg zs_-Nvf{K6rI?GF{e%Mry*slGHA_+u~`}uA)yZib8xh%*BB}w?gJao{qT&7m3GNxH}!6)7MujsoJ|x%cj|r1MU17nA^bIb-R^Gqk}RPi)d-!$wV7V9 zY-=>IxPZ(`ZklLrz4Nbv401Benpag{SZ1&B`nB#%pk=13ykb%Athdp_GftZf&G+>d zgA^ci21PplfzsCu#HwQ6&bI^@TkPQxypJ@%-1)Jv0xOz17wH zkdIb^H@7D(VVx#v0^U|WwwpoN`a=ACAXG?OZfxx9UuiHX926kSkO%Ob`q)@FL>(O+ z=0l{c%s*+sN=({;0h13v|CPp{ppqKTQp=c^_v?lAua~1HaTV1x|0vXNA>{iva@fSmm`jS@TmYbqOn{p*9Sfk6rE&(svA zA74%VboHJ;=E9V9iR{Ga=;+_S+WK$x;c&>tuZTzk z0IpK9;6k;@n*-3qpFeji61V=U45&jZ&qz6#L!LK!9`9vleo=pbF-V66L@Ot;rwRZ1 z2GESfHvhf7Jte5@lPvsXbDeVSsyg!izL$p1e?+I8ceYi5T-DgnkjAZYS8w|Z;%HL< z9F>*NK)G<(m*tM97CO&J*gSxxmkS3~8MUEyJ48~8fTlt`(h#5Vm0+O?s;@FTD4~?U?1#OX?}N$wGHtHrnagS?$3W_ zU4hK!9Yv~DnDnE~xwvmz$NTibL~Jx6|DFe^KL!R1hRC`TpJO&cSDKmXU>sZN|oiap$XTm=PsZ9c2Rx zdT;s{CLW~+KwSK?&4KU&jf~hQ!b%5XH7lBa&N*cC#`Oc^fi+D;?i2ER=@3z~VDSEZ zz1dN0YHBJ{;^f316Au+d%5jcaXqphEH7tP@$T?~m?=^IFbzSoJ%e!fkAg*JDwO{;J z1d-S666qob-=klk`p5)}UoPQ!*8+ICkcG*@#>ULXmM-pjebMr806+s-CBW1TJkS1k z-*0%^T3PiZYx0^c+5bIRUb3&Ptt~7n3gwnw8^9S8&C|%VgSuw=o})?o#32g2 zt5&$dyh_|z3!avwF%XcF%@DKNo!8V0rB0a)f*V0pEiB_H-zFs#rQaPPxFCS8slwf9 zL2d2;)gu#Z#*zkxP%Lz>B;e`S+LO5qP$BFJ17%;rUQ$tx#dR8m;PbwRz$*`G{HB}z zAwUb|>*9RX<#__EtBPy?2ow->+Z?hYX(9!r9W|7AxGm9dVDGO#i4?J|yCNArxnH-t=N}J{+pYcLu+Z$u`mXr)vRmRl zJdS`vULaT_t!FQgij&jxZZ=n5x-Z&&>|yjX2Sghyfn_V%e(CG8PA1yj=MCDl z&*>PchRf7`274BNOUW~p35q~L^o)SCyg$`epAyJLz3Yowon$qNgGic1ApVvug&SU* z7)!NDc;4uiHXdWO=MMYF^AOPLAPG=W$2fZ2aI|$dVu?WjJ-YLL{AjTeAQ)WcUA5l6 zJtJ+o?8KY*Zb2#m@D$Z_-}Qpma^SDW-FnMye@i+)V!Nj04uQBJ8fkgBxj?$_{{zNa z;MFTAqf6u2J5lO~*$r`TfSc0@+N=Ab`&C*F-(MjgTt(-dHvMJ7h@sO>?o$`d7d_5t zB{wzRH#LCvEr_hh)zmxert$XJpZ&4lcv6z5oaF4{qQ=Z2?y+jG<^miwJGIoVVe!O- zpijzZCJ_V#8=3Q~W6Jl!wFVz6PlGB#jV-N2Ss+yB@=L2gh4$+1P&Y?T`!sgL{O$cLoJejBb=? zfY`eI(Q-Y82JpGBrQTu)sUC@XnQC+QSrO;$)li~t{VC6-z@JgKJ1z5WGl+*Xe;U45 z{2$#PHe+%CmRrsi&K;D<9`I!?LF@jq4YNS?=SVjuffTe3pw^)ARHc>&mmY zZ=J%z!U)DWG3Bce1ZGD|YKY7EIii!%O9CgaUukyNFn~fs;^JixV<3uFRSI(UjABJxb z=6#O(qgxy{Tk~JGZ>76weSbbjC1{w#ayQn}fkpU0Wf#aWB`E@Xt<)MfLc5Wh+dLYA z*yL!_(b=r2r&Q>XD^DzeaTXwkE155hFi4u|R?l8`a(b07?f$d7pA)#)osV;yR~-i= z6ez3yI|YFv0j+G#=-AlUdVc<7;ybD%c492C!&WqvSw2!*cw?T>e*4Q_LQCT(`wQ0*eyxSg#F0w@tHtL5_!EQ%rmAF|56{(ilwpFc!$ zPRVIeXDSjjrNNLrSZL(RK&DtjU0vRU9Tm5^dWjO^9-Oa~z z3}p;mR5rYZ&^7})0t8dy?gD6zk|Yq{ifr3&*eKXb3$1KFHrp@xaa055M0U3EzY24r zm#S7`3w_BLvH;pvk%>6ml3j>eq)18zbrD=)q5C>la2?Ne;L62;?Zd&%ufz#9fG{GnE9qkigiDqgv7^+1~>u({;ab>gc9`neK5T zrKJV<#Ktr4>%eCl!`^#4h7$Hh-jgPHRM(5EMQ>QOem>$1AP!LMJHyrhHw4h%Q^QD! zQoG`6gnR#M-SvS?r^8m?nguUiCG(ld?{9zDblW06Bq(9j96Juj!Ig?ERFFsAc=tz* zu37*y=b9(d$^}%fpy@UC@JYRU{h7YmsMRW~;Zi<34U3H@nZ?!@&LQ&tzhv(OAXGPb$FI160+_{aK6xn3?kF!l&`qb8})d)d*f{%Al^aGwfAE zdqUD97w?wJnyKXZuGpueM(B|(m2zM|vZo9nW#2p;D_RQn$C!3dU4JPpvl4iUiZIs5 z-l-2Ed#dpAbt*b&aBvWk#_4OW<9%J=?YQ^rg@K2|j}<{>z^be;>jgw$BFCeZva{_m zwe&@;5m3l7X#$+@s|w4?><3d{A@6b|D%fw34_6HZs+ki@uLAG`<>X%Q+h{j?T;=x0 z0gjhDkW@WS>1p=%_wV;zTHNzXa6#*X$cN3GsCUB|H`6<%igZIri58R2WApwbElo|8 zqC)K^w=)2!yxHGZ9oDp5?VSuul*Xfj=w!{;cG-0Sb>pF9Y`g>n&Oz?nOGn^@A zxihSk2P`s)lavSde`DrL_GVjS=19N+`~Ks{!-~ZH%C9MdXTST-Pfr8dmtNS`W?N{y zmXflWt9O3<5W9ug>4*&Q@aTs!U6X$@n%(xMt*1(n+B^nc&Agnw-&}m{lM`O?g5wnIMfNXc~ccnk4|Kr`ykWLd|#GVDpSWlGz0%dyQFBpWK z)o7yBn>%J*I>+T?vDO(*WnF4eV?X*$TZ)YmtMq+&1?{_$i3zi^S7uh|Ay)zfJhFU` zI4zsGp$IiC_xt_(w-p~tf{m>$Ks$%79T_OEE}0}WbaaI5=5KLQ`E6&*99DvGUa)sn z+s;uGU+qeiEmZIQv7Xd(nLA_ED*1@`;CZneE)4ok@MF zP+9MrnFY^-rQn&F86s7pGM5E|nQ~GNy++Gq_3sOrYQR z*9*|bLQd;?o@e!sg9@BW_B0N8yLz+m(3~lxJy5@q=}z)z;&z#|#Y%9hmCV{kbi>u- zD3&ozz_7*bi~_!`AmO%q)J?tNC$sz#10-1X;A5@>jCFDT~uN4DG$Ls7YCMKqw$f;juB~?ZH?%lij$$0|}Zf5|I{SUnD?{5R2 zvnEbul!VLCfBpKp&jpRwtVf+=EyW*zNUCF`R_6f)RAw_%L52^5nlI$w zLVy+HJ(k-WO>p)!ySe%P?`Y1wM?ANubuX|e`uYo)8PzgH|IJRQgz8;ibATjUd(Gnt zUZ;`Z28)P@0H(uxUEQ;KL4rW~nCGlodV=2fcm4-5%bUi`l&QQ0AAff|1&sg_(B=A* zD7Bh3u5=Ghf*O>Ql@%{ohLrO&rTC}9hHfMwLrDaR?4uIkHnnhYARw5SLIT#Dfg(A& zf7AB&x;Q4a`6hQYOUvLPYn^v;a-D#Q5t>!9fBNsb^79R7>UC%1^V6g^ORzI>GzWZ0m)n54Lu90rjKkqUu-jg`odoOYf?aKOMU+Q82XCO*?!F!>H8i! zJ`=+o2pcB=0PQ*L znXzfOo@n;{K#ER6C7{7JhJJdT{h4~HmP!0o9Q@D4GffP_}tWB z+%6C81gJcxo}h&5@oHCB7w|M&0Kb*9&ujyVO!NStlH$q)Il|B!;V}I<)mo3!t@-Fb z^=F*t`OWhRAhRB_^MhBue=P%@zY_ktdw4;LEfW+Z5ARz6C~rCAn2}7&FI!^SraWD_rL7t)(@!+xPEP zxb@H^QVig@=W)PrkyEU5>o?eQaj^pbd=)m=_YIONU5A|Wl#VO6E;XEGsfo-M0~~-4 z{7>y)`)IIJ(M2%@{0|ySURB~DCxaYp?h{ZYQ&)vLV@wB>^O|jjk%!;3%nW0f1E*tG z$_T-21;3O-C%b&J#r64#oJ^2>@P9huxrIU+!5@II{aKt;paM&ttwcW8+kfrvT+t_J zvV`P5ACI#TIX`NqlUWHpKB3^^8MpNxejb3Af7@`I{}tcw@yo> zZzj1GXUFoU51E_|2!q-o`*|8$&9LmoxDF3p-^sJd0!9^l9sl73U$ui&Y}egdFu+633 zJsJU+j#6QT4KYKPCrfDmL6-ysh9YMAHsgIoPsbD5wQ(U}?ktK(70(h`53{TeH!<)` z1r^5gygUTybUg-B5TVqP&vagZJ$o8xSxLM4D>?&uB|5*8-{KuPjw;5w4~U*B zL8-RuqT(0V=JARQTZ*ss+HT{hkj6_iV@4mb0;T^rZSZG`B(=t!4u@%OPu+cz3yX(i z`Pr%}(jA^ytoJDjNxda%l*-XXvJxVFG&KFZ!C*~41@-T#t|y$;H7@QBsIju}B9vds zC@hSMib#osgO5MYa*rjjWoZ)_@`RG(`-&^aaNa6iCG39HK70~w=$gl{^_vhEq8P-) zwW1Yy7S(2%b**#a&PH;QV}K(ZL4`saJCAOOecLd}wN{3*#h!1bwColXq36${Kx(Qp z;4CB78$S7o5~)!*tj*fJ7-x8SNrG6`#0Sx$6424oZtGs-$1yTd!}o=c!n<}26(l=YbIh5yY|**zhrZ?Kiw|+`epk!ChAat|^MWYrT|9hJCI+IF0%$zK4~}9$^Sp*=|U;D$PaRSJ*|8kxuOGo>5sUbvHl|^yoG}z3D}oWI`B9%Z0|q zJ-%}J_M7MNG=tR8x5WdO2_ko(DBYM3cyl|;%YcrM92f-+9!zqc6^A1PYd zciiq^#=}2iLS=G-@lYV9Hq61f-2H}sYuF`rI|8HOsUei|5*yFNT`eSe%_8^6w}X-VQUb$aLWQmiL=Ml%-%-qe6O0Pu6<$Zz0_dr@k;5 z;4B#8S0tDeZN+wE9@yeSFI)$kz)z6n8dGXu?U+;TKJ&uP0 z(FRExAJ0VZNEys+Vb67m{hVedVm~Je4+S5FF6UpFjl$`0CV;z`(Vwj@*uh3`DF3jE zBYyQc1RsV2XNq8b99ItOC#AXnAbgkDDe*kdMu2B)Q%HH5JSyQDpw>)25~f0o;UCq; zq=f}jf?N0*ACgmK$NQ-eh=-YCE(6t^rp%qo&}FeT=}cbI|m8nSs!v=uG$1J@x%~gizoRs@$eLOY2a##$+}!!*y5%Skj(k#r^}f<9F)N0;E5Ltym{kC zIOP^eXM#=DZPWJRah~Y9oymAf$s?%6S4-h=uhi_wm1G&CoDe({B@aQBuT!G@yKC{@ z@p~BEuQXnA6nO*Z1tSd{vIwMYdz|MoGpXqqOxXxSnHg7(YKK>IKE5IH<jiob!uSs@Zme#awkW5?8$WpUOS&H{8t#!7r+i1wyqFzb^-Pdi#A9Q~qg5KHCb}5Hu1#P1{$E-H*2@!*T;jHCCI~(w zq=mvm9z=8eASo;R8M=arInF^A<0y%x_-~yoM-zGEk0;H7m&f+|D*q#i{C18$dI-#| zobHN+<+${SI{rgio_?r;oGh512Lk^6_8HyjOO-Ica|||KIo-3T*3eFyZ2_%G$HJsf z%Z%^2Q*UMDo8>WSkS?@?A}r%RB+`w?ef`1tD*qZ?ofrrK#d-utj-9@~KAac)qF1X# zQVy`>U(&K!E?;|)75UF_q%2D2q5t}&X!q>=B3CwHX5i#gNpdTp_P76mRQDn;_N8Ft z4>LT*&t3$)TGhbJ{tgC%La&|(edHBm<~EOJLdT}|cg?n2zm&`SOBn5FO1V}|39;9k zI#~`CbEBBMjv(~_ol0{M#6b3B2JoN48tm06rp^p;Kd!`r;^EjS27Qw)%1}iAF)!vT z2Bn4su3tm(L1a7(v?_m>uu~Xfm3S-&P$10TqW54+4dpzE>13N3G+kWnTbd%N+rux- z7<=TJ9L*IKNuq_5!J>P<{hz9?VANq|Nh`=$LkcYsk=&(?OXWFmBx zicU5-1#LZFzy3P!{WMTI-Dw6;Za>A8gf`GzH#4lu)@W%_0CB6FD9ZD{lnpGAH<3Gn zvnP~OD4^k$k`)jz%cwN)4j~skOy68$poC-F^Yt0EqyB?=gVvfe7O9j_^|*r4fnFW7 z+nI_k0HK@2?3%mH>veb}8X02Sg9{zWw*Qq)fff85v@!3~SB{Wl$ioiSqa_S=sl_i@ zq4n7;5Z6(zj$@=Z1ZLiaa*`7KIoG?b_26~z_B_$6({aRtv{#pkTrv@}5Xr0PvIomJ0- zVTH%X1I6e9)r|V9^)#w(SD*&o9e{#vHB-&)^IwLFUJ>lm6A%r%R8K7M_}%?EMAV7c zdG+Y2hv(Sb*AL(|tEub&Lk-6*I(qYDYg`bhWXCO&sdr%MtH&Cq_-9&bH_gM^nw>d) zpf*!fRMgaj*m=gOk|F-p-2mtx&<2HoRMKIODOe#lmtwjW$eZY(u=qBMh(+GX_NVaD zGaFR8ymKjj-mL_1K@n8$T2JWMH1k9x2;w7bJ6CyUDABV37nU!GjHc5*IAVRdrC9PEFAHq z@F<57O5V%WxsQyHXb4Xv7I1BJ8WChM4Jus8M+n8@5k3OYNtM2Lgwn}8K}s#t*TR8^ z8^-TF5rqo}aFPXJKSX$X9Dl%|AV}`~6b+Mke77uaMR>qOUgU*GP)O7YPZzf66J)jq zGqFj8Z+Rxp!|GFU*Np?K_iasNC$`rrF}F;a)P5K?`7i) z(io&+ysc4K;-Ni#K8wM6laqWhn)d@X_;G@;mf8lFzQYM}e09<-(taTUQX$|D=smQN zjTws{*#$#vR033`$`CXEBP?-OReQ-qEC54j?dB%{axq%<1TTVW%9)&k6xuG~>aRv( z!RU8UA>5c#GPdt!mSAnUixNo&{`NDr&21Ru3b?2rE9 z?V_2NmV8IO;aAX)1TR!*Cy(;H9V7A1%rkInDOFetTzcEZzULFO1)%e3xxTofXgE%o z^O2W?NK2xpb7fy%@01vFd3!NXHlI!E0u45RjoRpS_v;?cM~k{$`m*UK{>^vwX^|!; zoLb6^Z^TdO;v~#HVcRGwoS3}IL+7Ep5{$M=gD^_#HEb|a)Mn~$n`P~#YjHx(o80IR zd#`R~=mVqnp+OOh#E9QHIR|+G+}#q=V0e7hJodv#&k~W!UKN@G#R+yx&P1Z^BqVN`zd=UGLLP?=Q{9NpCl3qAFWy?&1JMtogb`jpq+;ACUb=t%?f@ zZnl4vdOi5#0dTQdtI9^=4zyVns6b19{`6c+NDA%2sgnkGv4PZ;rW0{M(pXKr9J1BH z9U=om1Aj#FN*x7BBTcOpiS$4|ntcv7Ama3$oFgUZOgW0Ay)k2jh_L%NN~r9i>Ve+B zzH%QQroN+RveD9!MUDZ{{vAvb)34SKV;r?FU29iO1lRhjWwO<^w2}sGXxk;4E}4=p z@d-9&9VpQu-}Xy5rkoQNOIFNID-bgv=C!{oG~Kv?(m+R2V(00{Z%at*ySQf_d^BAv z)I3$}{qI^m+==l=o%Jzt^W16o#=6a@W+0H>z?I87wr;w-_;|0D9g3H_G4Cw3YLvl0 z3_C)4P8!vju|aSw*>z#n*>GO7__km+!?W)(r5;J81J|^$A|4zoP+^fyqe*8NP(244 zT7d$0;rEhM!0L*R4awD%I(#`KM6mU&J2Zp{69f;%gbZPT@S#KF-f$g9oJPt#;*Efi zYV&7M!h`60MNCUZ$nhJPL*(Yh*Z~+KnGtT;AK27S2O(TFL}9sU4k5_t+ddwL~NNU38k$D_kVE0M8VwhSHVOOLMWYP zw8JsUFE&=WmzWtc_N-UQVd&|TQ4Vh@RmD7FG}uIRKo~3Zr))g7zRX?R zFs#UV-7Buht|PvnijE+vn>`$w2g*h0C_xqBrCFE*i7jq_dbIBQwd6g=8fEM!BgmV1 zF?l>YzJL1$Aq=&htvv#u6et|^`=Vi54kYip&I6YH!b8b&558$)yd#K%qcDDVuPj8% zjjR)8g;%wAahy|dAmHkSoX6?CDc?IT@1z77L&uk3=;g?? zv-`!q$eMGsCO9i-wJHi)Q+=*VPE9jO>|%+~(oW2a=Xu1UujU^3I<7h?{JAMD=+d&X zN-V=CK$*v3_wOhgCT^9!)lB_ar_fucc=$|>-SGY`UqwJjq$!?kL}PInD(QKbQs8wQ$884Msw6=3VYWwoVfbX(=ZL)E zNmbhhe1+@dTO%vJLn-i3^af+pcHCx=w>&k?!#BvtaRk4&vGaI%|` z9xdvnILk^gIVGjaK;uU^>hL0xX68vEc$5iRsDS$XKw!@i;l+QPpm4dGf-)GL63+F= z7%0CQMXqp}SrGI9FvEQrQG16LxuTtD9?f+d2Y_J;${tP6D_*WgG$g%b=3)8*d|NijJ zN9aFZ__+@r;c7-{D#Uz1hTag+g_%@^5Qvjfjf98KshoKbfR40u0sq9P^gX~K;NuCk zg~Q>^R=eMv>ZAAQJur*|vxVirixmPpiE8obc0qTJ#-lUba1+?TxcA8}9 zXAIxormV3ha%z`>z}3yQXFwOCsY&LN?y&qo1uGpd)JJU1{UgQp8PNr18PLRXFH{5dy}8&l*I5CX%+%kWv+F6+3KF? zMnV|#j3T%bnRSr1o6m*e1-xBkJoyiJWPEMjLfi^lOmf~3_B@w{E)^kJ+JF&6OYF4y zVJ|}HKAt#`I82jEmE7ZrAKsIV93DI+P}8t_eOx?1Fa}RP;*O51=E!}^ZrC`Svg{?K+)k!_7|Ys*vJ(SXk)h81{FVj zCK4?a6CEFpexNyBYz)*V9hK0Kt`Jw&>*;SPwR~Gk6mFj0a4xopW36m4<3QU)9+FEp{*{6FsBa z(bil^Oled%V&(}tT>$Q<6^X^Y4Mgro9hAC5FwT5*?Wr9H(`FlXBlt9iI+`j zwpnirl*}v?z!9rPF0YvBQeweB!+gA!Lgnr!{>k$M!bRm{bH zR8O;=M@3HRkl^^-rp}^${$gHaey$6Y5E%+<%XY6fYe0pzYO3yc6F_w{xSfk|{q^@( zM|Jg$i{d-Avu^dL)~NB&`TK*%@_G-44|_==(n0cL?$u3{zC7KfY}1#06B4l8Q*mP* zos{|Wa(_f7P*DXAb>>eS87|LBNxN5$fUa{D4%UXXL|y$US70v#uZJQp4G#;qPg1aY zG*7;RJg#J|3z?LyLRDUJHO$bE>+*Wy&vZmH>eUjL&oX;>yHgjo~ zLnB9p*$!fjV)^Uo3ha{ZlT`%%a{I}R`3r>xjh}>8Z)o0lvwR<37~75@uka~4z{fZJpv;u+F9bV+rAL!=l${H1Sp1! zYkyV;&yS7qkN{dWsCo}ZH%R`wSw-bh?UA$mtCm^K+oF}Bk5ZeLXBD{R-M(b7&`Wa8 zSYVbj=~8E2?G!7@)ffhJC@N9~Ej5H9jly3dAr=S65|isG6%;}X@4DW?q%j9@6`MRW zp2!iv#V5$yb|$-nLVCCoi&=;naaBwy;BF4vLNs$vpK|?Akw!I1gVz>_P5zGz-NcpUULn=pe6KeV)rz4>De}|AD>13~v{+!~JOV60#h4$~yaKu%FnA`rk)V z5PSXZ&%1uVQTr>HYc~LT@nWp}Jr3^OqN(a3**(B*LY58mIOEA80G5F9=&RFz!~KY0 zc6YhH)FUT>=#bp>+|fXx&?X>`UaGRuK@uY-tS>DudmSkGUIg4NoARsUJVeNOp#CZ( zCI3WR?@{?nPoN_@dx;Jp6n<)%SN;$m9h7Z68qYxkL*GqKe_*Q({G+Vp7xX`W{-jA% zxn4(*FR6!c?_{{l+X6?!hif%7G(eJMwkP-si1HUNGr{mN4{J zG^zp24zg2+>iqC9w(vERK(-Z&DT1uyV<V+{#P zP_x2Z>4$HBm2Do#@9ShaU+f&h;h+#Bz|8=d9*Rx`6#6e1G)k9-iw z2&gyW$G|^+y5I=)fjLCIxG7NEQCG~YZ4+PE0Coxtzf*Gl^ogen=y3jAea}Wa?=&n1 zY~Dj45V;{fEcsd!Q&Tth-eAc)MCptBx?B&3p#->*>d~pxY`UMo<8{eh{fJV+HA~p; z>3mjuy}i#+2!h2X`U)4@-D)PQ_kfKNk6Tcd)N89gjUj60&a+?G+UvQTT5^MdH0}KL zcngijEOAYk!$h@sgTP;mgf*GRybst!WbkDPW6GJJ?W8esC^9oM6L19{juakp%F2L^ z4WW!gkDFS67B=2|JlmWlWPd#8W3@mxz%zD7kc5|1?7x6lY9^z&s`tALKHX-e%Q9G& z4oWm%gFN0`TyJqiInaIr>_J#)@s=Q62HG6z?eBjFJSF0{`MWs7#0Prwk@f)Fet)cA zo>Jot$3h6*dQYGiI$if#f0E}aJq?r{y0yJMrm`rE3!%@O_qy2wbkO=hQ7W&c>RNFh z&}#|oh)V@_Ikk3EGee<@n$K@iOv&!+CfEkD#+ekM3Sq7zhfy)5**Hnp4kuA0y%WSDFw9qh?lG4y1K$U-HqO{(pO8$%MbBuj%Ss@Hs_h~D3Ju#7- zH~(RMs>OlQ{UUR2JT*-K*q@4+30DFf4lb^JKtfDc0NIiN1nW2n70y;yMRcooJ=c5FW7@U&1s91gp49tuS0f@lLi-4gHr#pPK|Zzu`(q22&I33jHKXMy;@ z?jyoF{Mv5zmemPWhgWt%(sUr0QF1_uizhm1Q~%bD)O2-V2t^?LXbD00KKdXE-FDjHaR$ITu6gU6RRgE%d)47@}t3)KV1WCJHxMGp-e!B&wBS0eFhti=6vSh zcQw20%K()_HFab$=SlwP`-f-(ce4|;9NQpdtL43h{jKGec&0i&K5`FR zrx|W|j!F7c71Q4-U-*yndF_fIIzyg>0Srn$juxzz91oURM;f;>>3R!Qqk-YD zaO03?{}t9tHZ~)AwggSLC&}ksDX~P;^WsGldcVlwnXNQW;z# zQ|qXP@dsva=Tn(fY#c3}HTVhSIYmkS|9b%#;4;gW$F-y;bnwujz${iyU5?s~ex3_c zFcwEVJgnzLP?{wDRSf_+UI*%^NOT(1m}R}J{dn~*Nlse({fh^C;NFsDl zXrXz;9~x0;siTOB)R{Hkyy3NeXMWQe-k->6ZPy}*nCAQW7a%&IvZ4kJ*HvXblUuAO zuZI;3@|bTsYU8*B>#*#Ho{LMB&@yuI?HRS(4+DkD^IhCvdZ5v?xFk~-{@(3)qKKUL z|Iu`nQBgkOeknl&UAjA@SxP#jyOHjeTDnstmy`}^_=7Y^mm-aXNVkZjbmtxKJ(uG* zJnX*n&dgK4uwgT5`LELPq^?LVI>jZOer6L%gO$2pJ+jsYu_FZ`)jvt12^KZIK9PuC zOvYVQiDGFHS18?=y1p>2?JF{VdnU*C3>k?#O@!#sR!cg3@NB@dGJ^UJnOP2?T`f<0Df%8Gq&crO&f zbkBIb0?R-~wsxMwp`n2=quC|(Inq}5wlPyk3yjZrZ$Z7r2zCvyn8(qyZxXD^$~hqy(KN-_j`gl zS}OLb4ThrPBdX0a!c3p?%lXeH%n#RCn#JK|naiViPj8m8ht|_+h$N!ZNp@Fe z=9$UHBtoAnaL3V`dY7YKNfh@`O-HWZ`DyG$dWoQ@!HGxkcf&|p`pf_ zE9B=M%x$XrVT8md_*%@rYe-3W8lt;ghn-vFKs$hu%-7O;Zj&ydTQ*;HcV0PFQb@giuT5FP)6%_rHcfB!ii>QG-10 zcs&_PfVxFnaz(-Vz7nTX@LDK3NG~tG0*2^9uL+!7 z(E8EoznfOw;`ZtfH#Z2Kqs4{={jTFhPYV*wKX;6d)s8`^vfW=R()4~aN=W8mrR_BMFgX`0tXcx+)FccVy9i-! z)w-V+&kYn$8+U6d1H z9L-8pSt%C}z-Mq2BlVe^7_rkeeW>KUdZ7L5vr$vMrv97Nl3MMz61EB-JZI{s{ZR;W znjg$x?UrK`W6Qk9miqj))ra8`vFqc6$K}<>z=8RO8wo+2b2@H&T3HAwmEz|JrrJC1 zxG6CcRsPasW_z9dMl^0n)Iet)`Q{()%}<=0Y47*oKd)?SRYIgQ;?7=CCs|;DKC0+} z(_#}lDOLaE*fSLpZ`#mSqg;gg7+RSCY`VRX?l#; z1m`)0kjM4}P43=k=1t!H<#@5CG$x6=(ZJ~sJ#ura@pL4ECWi13tj_{o4Eg4<4( z=LZc1Z=uT#+b!|?8d6n93~Xn`JzJ;($RS_9($0Fex3@R+PfuvI^p}$g_4M%aakV#W>L$$ofgCZ~l)K)(zpEH)_eVh0s823m-8WEjnr4#PnB|1>jzvozPq57-}htbs3c|+94PZv(x>v`XMBVD zT9Ks1;+wx87k@ll7wwG>WsVF*mVREHk4Vc7+S{$e0Bwn(Wdx9Tppkw9J-ho+pCOit z97Sp~QV&q?2~l`TjEc-8mWs@sXgN)2@n+6nwr5pIC%eXkHDf$Rza94zy)(-MxXXdnLd7UJ#RflKcacX zYmvfx=>ZH!4bq&1n=}=f8A=ecmVjL(XRcumDop^8H_)hqPkwDbXdAJ3v$EdHVSmkF z1V3XpDiRA}ra}EP0)6$%D=g(ltiP{d&xebU$il)xdHR6z?^$Ls>G-p=ros0>Bq7Az z1mN4Xjp)PW#~7IGAtmi_VnsR{A42hcoUL%Kk)9lX7Cm*?Pco`6soZN|B=6TJ0i_Uj z4cKZwTnQLq2gP6?&I&W-k2@o(9WBL8t2O%kyRFfVL{3zzsJ_0w&)IKvYfLB-{6jw! z*@OU!$H}*+BlY6fLu!E4Aa-|jX<%rO zR99S}k`)Z9ULO(X{*%hzbMaI+W{oY7`zcGy(>BimfG3n5o|_0<+klHHTh68Wm~O*= zO%XZ9KzbwzvET2h&30PW0hORzfOg*mb*YayLuqRS1Z~ULe zQ$3KRmB(xdjHK7t2`nD{Ib1#K@PR2h_+4+Nr)nPi{L|fd5wLGbSPxE;`TTr4c|fw9 zAi8zZjjh?#z&mp67y9uM&#S^kNIL3WNdKUcKlXHK4%eTYGro*)RGrQl54uQbat?gW zA_%p|Y(XMXWTpzbG9RgD#8(59hgu55SgR9W`x^bF?QzonIn6z4)rdb&;=tBlJze)_ zvx)njy-gxjGK%S;%J|qBxvt%&*)vpiDUPcb5^w$9v7MSUSH%7YcD6V#P(uRspF0rK zu%EP)MbQY1$b;UVXj!H4?cbo|Y>k%R97P_s?tidKH$obIc|E)gEyVwx!F4)g=u$4M z)eH(~fbRC|9Zclo=Oa+dfVwST#1eV$`zR?E$eXiZKmAd#m?nk$RG5U^Oj_s#O7yaR#s-JQ+{|)Ar>Hh+wjpfPj3xq$JMZWNDcB*YN7<>Z)#k8iF2PGSbkH;zS_Ruzd4%W^8N>;Qadd_#Vam z4=ET1JXfMu)C;CO)GmLMC-Go}45CUrmq4a|nw&4sm7#Isn%rSh2FMmw)Bf#2a><>y z9b27S=Yna{^Jz@U$xH@j$XwLOuR{h&-jVzs@)go;x%3ZSs@UEANCL;OkdTnYL3h;F z)md%3Y&U%fT9pXywl|=OA~Snv4hlMexiIwW@n*I8Bjh?`+{(sYFf>*-U36Zqs4;%v zzXMIj^_3M9<5@a1w6&d{q4)Q z(y#CE_Wt~hYfCQq@J)#E7WBK^OZR6qV}gDE6&CN$CDFyOHJi4-vK~(Pq+8=Q=F+^( zyAb5HHts^JR5x+DcJRTzF_O|ws;bB@dv^Uu6#`T@;-He%{7KpsNh1rAd z$Iw52a`X1EC`l;m$RcSa<$ZmxHxk6V?5FsAOX|!{{UeLu<%*~3)9+4vrC_PCo%R5D%<>OpXs}b zl*r8ZNrDWSg2ht_$KwP&0*#mkr$w@w$Gdp-T&{k^al5qJ)&Zx41T#?2%H((9$nH@` z3LPk_s7OvHQZAc%1l+?8Fzf^W>dC5jTF+0V`hChKWyqT2HsZ}_6}+X6HtMPMlXa%u zr}C7Tb@1P-hcONWhH<4?`}Rhl1CbjpZtfF?Xl&^Ia{J}t>Vsv%z}~r^lcN{HNM-PV z(vmWnE%5yU3k^Ld=iL1K;p&T0ZluV{3rgz+wuxqe>)eW2;w^X~L#wEk7 zgDzE(B%<7Y2QUlA#cmxRAMUeC!I)Kw@A{P6c0d13whAF6Y2;0Z43;3b$ZIPjp7g9!GPA)c&@T{+I#JsI$yzg zU15d_vtev^ZzBmndmi5&jhsi<&6q7M7u@n%@*q3~^krefs0YhUg%dGus^=|je zbiAx55+F2}Yrj2Q5v|kn2opx8fo8tz?d_!sY<#CKWIe2{pLQ5^O(PhQKYsXc*O&%f zZxWdXlvh@YXsXv*k64mX2Ed>gX3yg8Sq;P`Fretp+x>AaO{*6wm>5{S87;{URXbaC zdWu796Kh}*UfLdWm1w_7vEzN4^<>N`B8X1ByyP?gYJkH+V>!5i`5hegq~CJR>0^46 z9Q#Dls53fW6AoZlD%*_Zl-n;HZww?*h(7?OBz_P$4^qmtzOKVug|wf3lTX1O&LWIT=&fi9y$>a$r7m8Uw;Vk3EAgv~`< zbPAf*G7Rt@;@Rn0rn6{Co8|(FWx@JC7=-|R1^2WxQr4CELzQqVF zEy>QJ+}_g-?^EkHo(TH>3;)(gdgoDtFB;?5 z#gFF7B2d3!TRG@D=ZQXf zwm&Nq4ZC4QaGQ9*%|v_r@FtT-m!7zXV!e+j))h>+QeYH&T2v^)+U z&B)!d3a6IEV6K;h4V7@gMF&hg{QD@H5(e^hQap=@XL{5BI%N%#<#M81mc!RrgHqdGtnmm`t?7?>XzDV z$A9>z3n93+Xfjo)i}cB<6_VjzWKMfwIWIQ0GwntL*S9U_3b@k0NfTaS#7WbJN|@Q% zwKSJC+Xrd^MJOxooy%*WeL+G(qTl(Jub)_8uwqnj&X2u0l&dnI5f075+%non?QcyK zYI7c}4~KGNYvEEUYti#&mokrVBNy+rLDwPF^>PC6Nty^QMzgu63}J|GBrFOLqkuk= z0pi%FO&=XI3hPMV`M5F|nT%Qh4r)alfq@tGg4nVbR^Pv2gd*>4Tsg@7Rlm9Y@K;WD z1oIGg{~)h2*Lg??E+(X{fHfut`omKti2zY&o|S@&h(0I8Ktc|CiVj&T6c*VSU3nS8 z^+oUZ31)6c?B_Ldm@KjRno$}7qKfB6kI$WUi`Wv2nhAok71jWOlig%_zdcPu#jR|!ySm+$kmRW~ncD}CE zC%`f$8i`AE-j1oHMz9G<4<-wAIoMw*VtG&XW+@st&s5#yt0SmIcag3qcIlCc4%=O_Zqf^$# z{+nQ-Qp-TTnXcNGNI7=6)XJ{r8k6^z;zuA^=9)UY4kR{LnF7&M-_*3Gf(1^U za&;dx#cMm3)p|G;C?zGuAsc0-kMsK_TsLQW9ip9s^sIjbhJ~md*qHQ`(gCl)o;!(e z7>PcbHe6+@wvj44M}~%&PNJU8vY;R$X$Sf%zXG02d%YTIqO&q0!D1R9q4Oe~VW zNYTJw&tl2=2sX}FL4E`ld3{BNr>CcGwGk3TAz3?Nn7B71qm)KNVSv7 zxFcZb&rz8OK3V#SP>uo#%2QlML}rTjxi|){^g&g+%vDxQOAroL?hkdo%tL}+>CS4J`M&#uI|uH$15Pf3xiQB;r3^^%i<8kU`m?R5D`b%k66FP z&3HN=jzbf!=|9?3@yCw(`D|gzpWRFgBKY7k5hNV56D>AyS9K~qF|H1zO#=QGl~R$< zKQ}gN>%6(&)$In9+p#`Q*V;QWj`vt}x?=UPWC8d$NB1;CS9;fHa8^H#Hh~xiEZ8^b zdnPp0Qga(oV#5PkSF`ZkaI&$MwSxHE?}Fa=DmF14PPO;GQLgbgxH07d_Sjg71!Nd> z5G!mfye(GOCp|&WAm87rM7vkxct^XEM#Mw^MmZ!^|$qvt&R>1pgSgmNryY}}q>QOB@;H?o^~hP5 zZmlceZp+?y895OX<7PaoRsIvq>(L71h_g?vdSQL1IXqspYvfaLHQrq6Il%CHYwiM#nus;Zmy5LRXi40)t`Iu%4`wQ_XKuX zPn`K#+g7^PjGBq8!)}pj!c}_Ba-Q{OEB@rw*U{MwyFLxR>ZPJZy!T8}WB?e0zd$Cn zuCTEF)2ETc%aOSdm8RY6a^g1y*)Mjp7@KM>w=@*la0!A;5i%cCC3*xyoFVWn z_HSP;5SjKiiI#N|Phju6EN=bLuBpe6=;)VFOXm_H5!G}Efe`cUFe);z{H|SLl{Hx5 zu#l3eXWz-_j(h@5YQ`r#d&aV8zqDiYhs9!EFxcoENrWdlbLL3l?sy0_yhoxzd{eDs z!i1u)5z^31RN^ey_HcXGNjW;-;55GF;RW}#rLtoe=2vHY#WI=3kQ^>yvf{crS0HC8 zelwX6URKodUvWc2FE933CJe2?AaGtefs2Ds;cVJ1n8D|dPXJ#p508lg*4LJ=QSRw? zxa0{mBdj7Z;?HIy)^L9n*Yba{8L*fa*!bm|Rr+jsffr4e=oCU2H*eh1$4Yi_f!dB< z?-?ic3H4b#c9Zp>;H(O^`|$|`0|nl%9A7zU(@7*bHyX%!TpH2?9SN5}kU&~&c=T@H z`B2-6eE(sgo59$?soKs-Xkno7lZ40C4Dk#TGp$B%WqInp=l+FHrALJhl|+ohF~O!>KX6xy&&<<3!@s;(`tMLhDw3`UvoA_2=V zc8p|}{Vfv8l7-TCmxX8eLIjQl0!4x)_Xem~f@5LY=A%H|`#ik5!K8;`^Lq)wb`JC_ z@s<%$8`Es7dR}-nlR)=GQqGH_^ZzDqkx4MjQF9zd@fDTQklEk-Ix3I?qDM#}!^4W< zlky&@mX6%7-2Wip0!uS9yG%uv5x?AGZXwpcGD4i#(-vuzgfXK3@`PmW^|Lhxyvff| z*H7kFOsEoyr%dhT-j|@k{QzW4=+^T~zMT}gLpdB@+Pozr;m|Fq>ieZU;&hueYTOh! zjug%cB)NTZd>j5CyRG2IO%;v#O}qXX_~_7sfkOFA5p63%a;a{AFQ7%0ac$c*OxQ;7 zp&hC$0G}=zt|w3ETMgLzZpW+mbiK!&>3ba&Be(Wt1~U!hzn0<*&9>mjAP7*_L2${W z3Bof6pTDC#Wp`ssoO}`ujdSKExhF5!OW?6wdk}B21aianvzc4RGibKetzx3@YR9-_ zDW{9}NRsFVS!2Jt_?S}D?8{J@TFvG_kdI>R_JECA+=)~3klcaKf zq52x5wvY+IvtIkHn$Hb6cI`iowIi~~W&JSfQyoUpq0|bih9nI#(R8-IhZHV!ZPni$ z7pE;9NwVKG$gg-sQA@+>JV+r2U+Y41Jf2I`D|_bB%=&L?a{taKw*!(!1?qO7Ct5mW zU|^svV~&^~V&_2h9vt5JeuSEW6Uq_sio=v*14~a)%K498#4EGPB*V-ni8yxiXB%Et z@Gluj6@FM!P&i&q$^o#}6NrS^aH*{XZ69#`>FaaJH?<_vLH8#WKdAXv6+@ z@R?t1?6FXCtS9_V3ms02E=v!>gEUQ**GNS7df6Cs;ZLv6rUDbhkHdF01kug;3&~3( z|Dyk5v-m*&v}cVR>J>y$kN5g|E*z^UBCBB)rytc)wSO>_&_u;hbRee}2!07}j9P&v zDNxQ)V*CK~_-=9a@ARV^=2Cn1ax&ouxg%RDN2u<~4GqsLvoXGW-TJHk?#j^|qCX^4 zDJ_wrinmseDZ1nsw^-n@rxAW*h? zO#S~35OErrAw(~i8iJ40gEfqd9EoLxQaLzSOzMBHw7PG#{(*gX5(o3LoeXrAr1Y9~ zw~}^#wPWzy{?BlKpWvPykK?{Y?cDWlzZ=`YZ_8P6K`+uxBGyNU`H~r}RRO#%NEJIe zbp)doGyE1FT*9PiZeCFFpPESB`A%8hTRXcb*&?8hMuaWhu#WuFKo!n*K_^koYWB$wEZ_5j=fJT z93}Ox)c&TU3rJW!Oq0GnRj{b2s9axPC(}Rs`#X)G;*T@EZbAC^*6HnCMxqsW ziQ&^PS5JP^uy<2MhaHakhEaCg!PNic zM~PBrV4yQmc?(OXa$w7SZ&_XtOYRI)LHBKY_a}Q&$)hX01j}%s3rnD(E{{>iVAZeQ z@HXn`n=-!0?)ZP$_8GFO`sVSZ*mF1ftOw!Tj(4lb%IW5$c!yR)%C9W@u_On_O@i-% z8hlnMQ2cv5e)$oo%K6gcGKPobh9zypb^U!VGL|=aYDrA{g~({<7O!N~mA7y5Hm3by ziGwHH)k)=Vo#g-vD+{M_TQSov5W5Dz%*(?^ZTd+L1CNANDkgUJ+snrXwSSN=@#AlJ zV0}<6^^*l`dk()Y%|CxGe3aB1MIFm_L}Wy<<&vajWf(!cN$iYKFkCTg#>A9iYGP8` z(&96{3v?W-+PtdnfuI88ZGBWYt%^0=4E##ZDot(hW3Rk+LyOczv&6TpuXAxbEG<=M zT1hlPO4NMaDf-b}^uN%%a2RDkFxfr#MG5L2C;|gD{PdKRlr*vH-!l~zEI41Ny{-p~ zPe;img!X^Fw)hl|R%8alfRt+|pDO69BjB`2SMb|Nr8G9sgXC37OHVHw#O(Scmf$&< zjBwd;ei9B%-QJ&X0B8iUx0Pkx9Ki5Ci;b;t zc#9kgAtm@lwb7eS&H{l%83?7INQDlxkP0(1Jf=NYNM?+u<6w=US1=Hwh>PD}>0CU# z)$R3-6$k%yIn|U}u40YR+jv z!E4kv`o#UkO-&r);vPWB?-egEn_-vZaiL7XUBGlvT1pzNM24A;PO!sIv+$$1ohQ_o zH%UFAp^moUPG48m^U5acES^0=AT;zE<&Bk&z3<36C=Z)~FuP0e9xyW*f4&(B1lN;% zPydKNTx|f<^}mVbKYd2dRXc155ZuY`_8HkY50|8wY&~`NM9CJ{LQmV8VX8}Bbn7cJ zBjjFnYgvCV%={dBTz_`-jeW zU;^AGKmmr0g%z+RylU_4Oi4*1=6&G^L}~%*jrE5ow=b7h?X$SlN!An-Z`bv2E7b0S zUWL0B6kJau-jxo`R2!c@+#aeWN2;cf^li8r&wdQL*`c~yL#Iq=?kMai>gOfq@^$CQw73n&(XO^8(RR@Dj&D^<15PziK>S>k?}XK!M6eh2+|M z`qvWRI7nhVrxYQkh-TCp@?N>t#W4lFUW4wSK!?3+v}c68uU-KMj(=C8a<0&M=GRIy+Gy3ldR#HAqmYcVyCyj(jo;PsY0eYf0YxgfiDqcb{ z?lw&y`al36WH%6TxA}EGYs$&Qw10Tmt{)c!s>{hW>5>#LQ9!^a%n zI`BI$XsfH&zCEvqxbaKaB_SsMha4ZvrAkjt1&2L6tRUSaU}rPkG+r9B!=#2yslHNO z5~p7*ue+&<&=ECkl0NbMr_2()1flwf!>^L-5}>t_(9_Mz#H82VWe>OeuRGXGla2#) zu!0{iA7jmu^YRXleV(8{A<*$O;`PZ%C*JrRM3!oEX-?dXA7%1Wou8K%){j~->k}6* zxD{gf%cDDRaI4ie8t6irPXTkmwM13W`**?92$}UHLhj&4g?9gU!bJ8v|9BI zfyS*g#<6eb&vF)&aCYnuYjyhsj=C%6x4(o3@9OjC8R4)oNInoI+@E(xCIyf_E!`U9 zzqHF(1a<^DuH^vc=%(A!t|< zA$ZSIP>@-$R4MphX#hG5ELt@KJ+)zRE<5L~HD zJS03MkS#>Cf%#Y_y#lJ`*!;8Z)2~2e-^Ad}Mc%_yut}RoW(5LU-~$_IlU1yY+if~!%2)Z z)qL5Pv2;+gtEjsrf;V{qRx0mBeNWHR{+5ciw|g^Hz@+z9qmAI> zSksP+1vLPhc|2%8w9f)dQ)k9Bx4L@y`-9=uXeQYaI;isU9&V<9B8Qz+ZeEY>3E#F7Z$r2be`bTmmVkS_S?jy_Brk&0`D`K z&A0O-BKD8-tH{75J(OwAvee|#($c?+;t1IyWJf!Zfn11)7vB$w2sV>e~DX zH>?eX#kiR}dHq5T;iRIm`|H$)O)V)E@2?ecyymMf$22QX z3Lj$ClIa!j@QuND=IpxC6d|1TjDsR03zJwvs_p%H4jvls#a6=>EFRR>0Jk?h=_05=0#h}>7x*hrtLyn}L2h$TRiqKL>OARzd6f~ym}?|Xp-#3~h_D~3v}T}5xS zm0BVMwm?Wf$l`Ojx$zSg67t%&3;L633+9&B8&uu>8P@=4RSj@P+g>ro@+lFgrzl9>c5z8`6Ncl> z56h4D-jjAInma$sr^tN_9Sr5<NsIFSVxq`UNty+mn%+pFe-@ zuLeUbJA8(c|NOCuR`m7twb@-X5BIZw^mO^sG)! z>I45V0fEHybUBQ5a^C$05x@!_pp-(476Tgo$a-m7#UUCFMz5FtWNP> zmYqq{<|O+)%KeTDfAE_y7!?RR5`D)jZyGzwcfDp8X2_1o`ny z?J=CocelLk$;~a-m-Rb&+9b14{5EYSe79ewnW$%61-!jwHZ+l@NbuQ?QRLc|k8%Eym^W$rrML2*m*oJXX=SI+*tqB@4)tf~y}Ztw5fBN=1i3VVwIyj&de`qk_jVrAQ$TpU^q*x5 z@ch}xP7P20lm>^Y;*1Fve3N__h|(m*_>I(4lprPvQUcH32yEN&oJ|C$QHw-!aqf5F zLOP9v*;r_SLQ!H0gRa&u{@Fb} zo(4ZG-;|z%gI`ZSo+ZjknPA!#AegDVQqW*c%((T~v_>D|-o4t~Rlajn(3|5PX8#<4 z4cTA$tR(Obb9>> zxA>ixKtKIq1GuvV{TbDlNo#fvtp9u-5NLc4mWz;0?`p*K;TKT31If2Zm!qJiBaku& zDk6b9eMB3_S54l{u4AC{`=-i35XgdGTwMH9KUby4y<80r_Vk&`(7QbKXe62$n!R5A(&$aEHe^g zhGRz3ImseI=eE{vkVEW=Rf)n3H>&cl3np?m*AwZVnoDDJnh)|Q+QW#+Ny*!)KHKWP zBUjvc#(Ad-BgT9mR?~5(C?&OFn@0h4Dq${R=wnb5KR*N5j#dA|dn=Y`oFCW#d;_*J zfXQC6nTHE62v-|*hH=?2l93a$aWEg>-UHU*Yp~`G<6?_bQ+Npj;DJF#_#=zauJ*tG znD8-yxH?m&GN|3i9L3RPqi}c6ufZsc^7SV)R$1Z=c>!DuRB5e3u-Y{SpIImq{t0$d zl9P*gS8r}l(m8Dz%23i<@m1vU4%0L?H%Ed|2ja^YB%7?%)YMo)&Ng5uU^v8>0aXOx zov9ss2zVyMaWoOvl1MoUqCwEz#$}va#~NIq>R@Pyu1f z$>}?|H(VU=v3vD8?2;;(*5N)|V>YPUr97(pZvLzlEIF0Q^h5PV>gvQ8S5&~O3@F~M ztgHZ6lz%Q-z{t%8lrDCpOUqLfu>%A;V93v<5>dO1O#RGg{D9vUMOLZaKu>#VaXQJ8 zed!@`n#(VC|3|BR+hKJf;#c-?U>BjfF@={SWy5l$E{wt{ee@zpCEVU5Dq1Io!Np3@3cddmJBAX>#fobp7>h zb3_+ta&s7Wq%@Jzs?I3yW_1A?9ncF{U&oo^mE$`h>pf){so$oDPkpw%#N+Bm>NcI& zXTOvP7Br28yIchXDGm(|V%&6moYo&jvz+`)0AV-s89zFz-8R3F(L+*>h~2vpd!?fR z@L*s?5}bVZdu-8@%dJExfz~$}DJd@&k2wC@oFBxo10cYA7=zd|Mj$iex$!Of!yLh( zJmZHv3K1salx<+haS~5K1q=^ZQx)Hb(a306$prmQlJh=re1e*SJFvIYsP(~GkUakE z%)_uY5j8z6&BI%YJM(uA&j-tqz636skPxUO#&W%NY=s|y`+%cpIjLuBYfGDiikg{L z{Gn1bcB^b^2k3L(qJ&O=(hWYFluKp!?n>*^pu6Pcfp=jp7o^ljg1e3j~4noJbQKl}22fk?BZp_J} zG5~bfy!-1s%di2*>7meG>T&!lV3wVy-)QUG(w}fbVAk8ls|N zEQ@cief8d%iP#F^+p(g~^k2m;pv?Q-oY`lUa`k(tP!SW~Q9W*SM@n9&;Od-9W75{M z0gKgx)!_Wv+9UqOAfAcUN6yDPPO&^Seh=Uku$@A`vyn@smMipkd(sjhjSg2j!68(p z$K~w4I|1ltU(g%_PBj=;*u6d=D;C&@a4yzlhO8_uDwQ{a!fME>zO_|<)>A{K^S<|Q zxyRcRrui@QqTbadO-P+~W1bmsw zU&FnVwkNcVjI@o7DH2`+b~yZhKl7sRJ#!aB_QZ}lYMd6S?e{E-=Ue=Tj&Jb!QWgD0 zC}rOK$ZB%ii~+;|potGo%KdhvxN?amM56X;ynve6fuhn;b<9Ui?S&=6waNdo8uV?L z>SYSxU~ND{g8BF)!(n3N{6EU7i|3*xWG4%#4=hMSzxffa?p(> zwGg)?=I=aAa*%zS4v#Nnz6hJpwl8oMFtA-PfO;*XbJ_+#n zdZv57HUX{Xr1g*xwIbOT59vCQn|gcWL9H$KmWMqms94%}_Dv;|^j!t0r@D~Jtz zI0-Mc%0>OXi14L>eJ~p#Ft+3?Q_Gw2G^Wo-LI046`hkonrxX*B@b)}`knn}PW%ST)?$$mGE-xEczScO zKhGl|AkTb{TXo_rje`#-0T~F0>|kgI;LAV^M;27WpsYJEbT?(f2NgaUzf*_Daq{Zn z2l|~YaQA~$9Tb|6R);T7iAEp)IdTGqRZ>z?eEeA9uU{kS9H6hMqQq&~git&Kwy@w4 zfLFw2S>D0n-X8F$*gxDOicX?Ff<%RULNT5NU+3?+5AX|F_7O2B?w@b41!Ak7$G>EZ z`MrQIEC?zpQ!;5ygX}oVTkC-H$YqLH}x zlknAC!iWE~bxj{_gD=Ve?p_QqSApW){{c~6j*Y?kK|=xDRk@s8-zUizgO(kV!RNQrKbf^6A|ip^hrY3~ zC-C76mq^>}=n$!yZ3lMZO-;|HO4STOi-L_ZPb^TV|M$b~?DWixENv3nDbZCx*Xfp_ zDCHr55c8^Zd+gx4CAK-2BgZkNLcSbLz=MLW`iM;5x^%w+wVpELd#?Uahpa#6ezPuf z@atbC!17c+*-9Z9SZbWdxpXY7uI9BK+=dA_DsbrFak<6hq`TTyL57zy}dN27EwgarKy1BU-%!R4%S>g|VxC5t8nzqho=ofG+|2yB{eX+0q53&+ZCH_Uw-S4@UVxX95 zu&F7Slfm!}njGghmD07!&nhz;Kthx&;3`>6W%iOK0`-6er-wYb5}y!X5cACLwdcrP z<*aQ*5rL_WP7*s`e}|ffSMWva7I1I|v-5 ztgHj{y?dp4+e%;JDJTyDFg|EwRQde`xODfv;nW?Eiq_Wa-PBK$b{7 z8;S;QJZ0YWS2|=#qqViwD<(74eF8<}%J;8@v|+9+sc#5M00J&;lT8(!g0%O7AJQ7?37FXZO&wxq34|3GfJBzkbb<$*tmE$YF(GP&n}sUA_BrXwvS*P8xR; z08pYTz0%Hb3q*g85z8d#u>qQaTAtuLXmwT9v7boZ!Rq7tJEXWcEkgFTtp=1lG^y9! z;)ydqK2-b#L*#;qvz@8ni-x?5^9vlskkgsds;%+n(G0H6|Naw5Rlc}5=bPbg1g*7X z1^TruBO2SXchPiO+!J~N4R&9jMR0Y&kAHyy-SYr1YQk8Mg|O+tsLTVZ?ib#@5W^oH zm&3Te?*i$N9^1#L0nj-GCiO64gEo)(_f1W}5~&*K(7+If0b4aT-*fbhwG7|9**(2Z zF8>L-HB)0_syaHVxgyh(D;(NhWiBICh*p+*W#(yKCo8KK;PM5|EhuGyebNF*tSc&F ziP+<1Ex`^36)L8rx}KiL#XgBbp|y1hhz%WHRifZHhN4pn1YF4r|r`um1eW=Ew_B zlY_r9yZ925772-Fu4yJWIoEZVz#J>XT{3F*u%^5`a4qzNWNB=9Z^3hjNhzaZibtvoK0Nq>D~6#jx?D?UV}J_;PLRuY;i#xbHtZ z%zleO4BbpHwbW^|O#5|xZZEq9*Q{gr%*ygIMQmSyi77C>Z}W7x46IiZ7+=CX6IeKy zgC4f77P>YbIbKV`a6)9rTja+(<9+EgqFv*iU#%4O$#8weP{5eh)j2;qE6p5&{n}<^ zny_qje5rX9%gg}iqS<`zf4~U*#}4lhfuto>+KvMrO20soJjg0Ow-jI9UBBt&Rqi!o z#7kjhjj^k-+!-CLQ>sF!gu}I_{1OKKu|~nTt?bK+l|P)6tc;gW6b_<|q#Zpj;AvK~ zDS;&dd)h9`hP$Dt0aQ?U>71q)J{`Ha6o8(R2mCj04}%ls>GwNPIy(a+3d(*k>u6*S z-Q3?hd>eXYwMGalAQSQZQ-c4ahtqKYn9CI9vvsN2? zeP+F*nzp&pwL-x9rs<=2o?=NNS$|Kb;otX-ZE31uGQ8EuxkQ6_N?}}t4Ad{gPvDkP zy&b-%)kdxLj@Ks)N(Z@OfdI5TZiQty62@GD0WI-h8`!fOdj%K90qoWZGtFEa0;n7)NUs&~- zoiJfD^5g}%05n?qpA-~ud^Db_Hg+I#eEvmuCP5nYBLoT$dbqpx5#i9-`RIQT-B-A| zNiZ&QI@%SOx826&aU1!+-W)el2Llnj--6N?T9wzrFs6378~&f4lCS z>=pd^*4W2fFcL=WOyS6au~f%QkV>H@8zElneh4H)Nt-s~_t_C$c+>-aat_*eVdpti zP@sM~G+dsUNt35%#Qo?VAdZ(8EQtY0rhkf5QC^Od80LK0;P9Vmh%kzTuCA_%%J&!o zRzL&*+W11Ls*GBY9L*u5MV#|s4hJ{K<-slqDC-*?0!udTBq8DUCYMJ$Gqbh9NjhY{ znxdj!m@-#Tv)VHV*AzJ=Wft%Z=M26c0n9ou)EoF8n!Y=n>i_-!DAgfxvI}KpWp6Ud z$e!7I%ib$wWY6qP6ha6go9w+pcF4|t+v|7txqjbsy|4c1-Q^tT`Fh^>{aE+vL5ES9 z0qggb#&h{h{u-~-eV8l4J2Q?6s1iP_XebU%k5ZXo;aQ_q-%sCjo1=c0=Ql89fP@Z}tFjpUL~7tJ zI;3nqZ|20(jOFt+?tZ16Vy_lrz;3$nGYPgw!PT(T5g8a5Xdx#hf^OOq9;`61raLPXo49OA9`ZiRQzfAp|6FVAb6qiwKgTPGo@p4Woy; zY|0UgG%H4Ji=J^Q@G0utcJ|J_0m3jb`2&ixW5)W`Rvh8~PA_u0Y0c{!vxSn0zSzA6 zqK}wrz;J!U^ZIJ%T3x|SLCIkcHl8~CZuX0bxgT%w3G>M3cN<&BU1Su0+^}_ru<v+nilyB~k;%lz2{ryr>GSJ(rUH(TeU?}h|kw~^8c#gq4eZG=rmm%cBkRq+j z06nD1;f5;EoTd@t5--)h=s19+U~$nXBDAm&HoON}D2fEy!Q$b^i=_Lar@)5S*)JHm zxKws7NzuG|6wMEl|C*%AC}&(*y+P*SCZ5*GO7LUb&!s$a2Zs|ruxxVj$ZCreYT(@} zpA$n-QDaR_i_x2MtyHaWwHJQ=vbMf%7;*Q>%h7Mo$;qXZDO0{q)lgAO0sLH`!j3|M zR4dF;yOTElm4O8Eeqj@})MnavmXOmMYJPUKd0c{+7nY(yc=uOGu0O=Dtgdd>-p9NJ zj8UAzTRF}YBI>Pxs#%MFzO4s|$$OjTYnqab(n#3*&F6Kp%P}bMN>6QWYCMb$*rvhN zQLcN4P%AN}fX_YzHyAdX+lJ}rbM;CmSpT!x;i*XW2aD8f#Sm!~Rl(Xk zj5Iv&OjjhS@69T5QRK^zX~ApOmZ*m|{Wv0|&)o-1G#}hrf9I!NnbbwVe+P9dDTVv+ z_a`@8lG^ruaho{l8!GymTgo5U29b*qVjbLAmL)Ua-gb}W^&V}9(U805Gg1C*+syZJ zZ!tp6{zYd{_>PcvTFK=e}Cu7a`@~?aHS9T1}gwqNWD_adUAwV9O*iCz#e0Z;3!s)93nb zox|BVda>BodU}eV*lKKeTTmDjVL2xkLbN#DOM5}B3$)cjHPAtQ*Zmu^6)y|UzlSiH zrsnz0MxgY~4|-#h?{xiX?HV7YBf$9-5cd8C4X?1U7i=7U%~|Wdw-~k`24FW;fWV_e zb(k&KQ!akLJJxq!2n1D92ZPY8ci$(meB5aSh8DAdWIk5b59?E~?{{i?8dee)z+zi) z@6TUf&W~~ySC>|Q{@S&AP^>>MhRlG@2Ee5}xr|!t$$g07fFa&3oR^X~amE773yHi&6G@0wZ5hnwmig44r`s5*RH3YpFuG zWKz_)E{BIO@StHoQdJeq)L`uJ!xNFBY22yLTymsg=Efv8luCq0K~(f6#RS}KtV)%T1mv7Npkh!ln~`rH z$24DN$S$BbwC$FR>Jb&D3Z31W@r)&*c9Z-_r$ChAVV3>NwUt3p)2Aw(o!aC_gApZsh z&vo1s-1PJeptGT(8a_L_t*M6c*AOrx&O^q8GRq)mhN)?V?>PL<8PVS*eooFQD*ZW! zE|$@}KbpZTf+~P6;ia(=t_Xoe_P60lRbNhzh(i>s$Q& zSWzhW)Y|d%m~HJYaM5$DI0q1Nrzp}QTMBceW7{~m?8Uwhq|3iuBwWZQt*9fU5Ig+5 zyu8d|-uJ7*lc#L&Cbe|I2RcM^2#TSb{mCCEQ9a@%p!T=7Gp|pYt|g>$2nd!vJYGZ$ z$Fxd_Rq8}3a7y?cy=edx_raq_nZiDL&eWE~LGPW7&&VY3K2b}xKWQI+t)fwE)Z~Pn z_>K@ou4vM}dMu@~?=El}v-^~#Nk>=LlohbqPuY!EYh}h|uYYpN5v_Jtv0^-l?6@L`79~lr``Nc}SeJ$_L$0x3X_00cBsmu{r$tkjq46jUgXEw)rs5 z+LMHRFvcWQk&-%`mtHD%2(K&I?LMP&Ldd<=1g@`a9dVvXLkK>5iF29!QD9A;sxbj-OLbqma(;CNFPca>y#>-3ZZWGIa^vV8bZXmHH z&QsFUdkd6oVWDNTgrLhl{trpjpXOQK0FnlAJff%T!dZP9#?LOGqozj~*-@_-J+V0r zkc3RHM??%`uitY$h6DyCrhCi5Y9(5gKG%MJEq*Zh0S2WDh?#a(Jj(HKN_9BMSCOF? z(^yvRj~F{e>OAj_y0Wt2onyP{qqLw7$jkwie*}oBs3fB33Z=o9%i+0=K;=@iyzi7H z#Ja6IR^f4w2YJc^CGr%{>9cipX93K9=6RIf6~iOKg4b&)Hz z`&?ab>&x2W`#km!h}RY0zIJyf=5_a;tF1jNRjlV58bGp8O^sexOTXo zp>|#6QS#IrtQ`Sc)EAiP+Czni54l`YvAnB7r7S39x{$ZlC}-B7+umY3%rCLjr@rO4FXYLUW?0;xZ z?yiw!{A1*`_g5~xViZ^aBA=<$H?cmE*3%;=#m)k*?sV1X4xWI^#?Qh+ zX^BRHOIqL9S6!!C z6cST&sYFAf$oZIYuoXD!o<8MZUnCMfxNIz?^Io{i!otivwRHq%ij${0B0|S}JROx| z@o?|}NvVW?=k{%<8ZYLwP1s7mz6B5iW9tn{^y-CIJTjCh$~MqheS}wv^KC_gG7UOJ zz;9i)jN9BAgz1rdxhuTtgukn7?h6dwt$*KbX3agV-gE|U(-lS&e~d*`r-K>CO<(ki z8qBB945Z)Ir1%(=dcF!Ldx1_7$7@LEs)XOT+s;xFqz?Q3R##SB)k3*%IiW41Iy2jb z?)kI5k^v-NZxUuNh&AWo;#zjCp{1oIB3zlEi~+cHtL=VW|EkR$?yrRfjBl&7n1T!? zV}H)f{Dk?Mmp6oso-lk+!0C;dnVPCfQtN_a9S<(aH=XF5wBI57)x<$BSPgHO5gTKE z_Pf{0it^9$JX@FL*NqRWEqM^sBIdx>5s%x-`s+cJo@}VYZBZlo2+VBpqk^7lyUYT* z#fsm;D5RQ4VfiH1xxQwMM^rG1KOOr8zO!z%R`Jctn`&t`_V#NK*;bS1%{h?SAD}yH z)ykSKZ|>xD0Ep_JKc4{n;=J5lXaz%BYT@KxZakv93^9GaOT59Y4rl+Zr=+AjC*S=U zrvTIxHa2!ZYY}KA_uSLPeG3csNfnSZ$;h1M2pQALi2GY?b|2C!O`FA)Kc0%1`(D~gM`)>u6G`C-0lA3i=@vd5m)-jS&YtA zU@ef3K(sbv;i^6G8^XM9r52d1*H=ubsn)VV<_we!z%%j7x+;x|3PnMfx>#&Eg+hqz z3UaH7AaD6~22u1nW-AIn$3LN6SznJu5pNo3o5ApmY%P4J>9HjeFa%2`Tqr67W)<8; z{j99HpV;yGs>Ei8F5fnlko;vr`mY_|Su6wRKVXA3I(nm=D+|yP5(g>0dNn#Sb*6v4 zS#7H@dm91r%(n+=^AVj(Z?opjs>LaXPfz(Osf)k1-cATkY%o=RaQpYjiQ;pY)(`Q- zw>y$qSF`IY%ZdzjrtbF}p&2?=eiK(d$WW3ls8LT1eb;|HP|}xvr;vodh&~|#1u-1P z0O@t+_emJ3&v_WT)n@f5Byjb~>@l>bN}k0l60o`(Im94JXjf# zPict3v1SZfM@R7NhoGDu+W5j3IMvKu&(ah?rOyjoOq3jypR?8>lg9h z!K3KTb!Ry1pOgzgv1Tk0Ehj5m&UKWrbFsB@>-4Chal^Wmjr*vvD&p|8ptU(j96 zgokjYOZNvgFVw4q0%8vjT{L5o)DyussH0;dBdPW$CWb^tMy4=FW#VVwK)+ObPM!ry zL{-&I?&5EKS%x6#^!DnK(!Ka|3)dS%lT&O5rS{KqlwNUZ#)P*o!WPALBZ%>O1R^<^ zKPZ%lia5P=`{d+gV`C$vNy3D1ec5!aPFcpr$%!BN(nK>eHI?6CaaiJ!$Dbd82ZZ6b zC{8{;zI<(DWMoWr`s-tKCg{Act{UA1w(WUA41E5^Gbt%)FrCj6R3gs&3Ed`Ka$L@$ z6OqLabTHBWctow9$Z}Kl_JC|Xi_cq2X-tt08hHLVC6)G}d&q2ZOk~d7RilJLdUASt z-%7dnr8jWxJB^-IBNp6oG*4RPq*dMZQ1Y1qd_2P7nYoQ{uFfm>Lruc-+`fX~+9 zL}zEGx|-Vf55w{_)a?s8wUjW!Y~LGFvEvgHmqJYt8V3Ilq)#0LUI6iw0E)Sg5B-*S z=oA_9q6m$RfxfabjoChrl<$~rHWGo8)>Z0y9;POLUJ7N+qc87Bn_~cxiP{Cx{lVS4 z;mB;Ae*FcLb|%|dUhtEWdOh9bCEt~nU;|;%*jL;-oCV#r2odk%#1s!SF>0xLh7{m z>ji7@dvZ*_=euoG(O&k;`=NNWmR6SG?UWRsva`#IEBjd^F7F(%u$2C?b`5T|t<Tq>bCWmA#{^oRQA9kYC^6M;yv6%% z%r6h6h(OMiyahGG0i-aqawj|b5HscLaK~|_x#@RzbqsJ+{d`VN7m|~=Nt1)1K*oTl znd@Ku0o4`hU}Us{LFEJjcNHHoED3qlzwlq3v8zPeUb|X;scz>vh#y;Ebx6-@z;0Qdv zU_UI)kk2n!KNS(GDRbByPcGRkXM7RzHM^>ED}nm-Z%W1W*7ccP(`momS3j_{h$->9 z{&lCuWy3NCEiMNKheQ--~nKDK06Ijpo_HTmZ0xmc0~QqVfH!dgS*jGvub(^ zhWt0@Th;f)^h%G%?CQf%ZV&+y6f_igKtzWC`R=Kg5MekVFOkvF<`t8U7FAOWL@2Ro!g*?s~`PLx5S>;3%&% znX|Urd2MYSPu;!cnna>Ue~Z+=zS$}jpe5cmwzaf=v)1H*4N;!&B=NYxtu4NHe3hv& z-7G0*#*Yl|izEDU=(HmU(Yezi6RzO-YIzsT4q-DHi!$|gkJ*g3_vIH>PM%96(E=2u zL#MYO9`wK`L%;)|L~d?wvkFbvtff~<`81Y#J!pX61%b#Bw?=Y(5g+HJetX)h|7NRl zLj1+=TNH%h3JMBuWd>rUJa6c9=8w`|BS@JzZFp?K3k_NyWB>OfWz&RFzptvJR% z)l8x!h)2$5Dh6wGO29rhXjTn@2O{l8_g_Vz7Wqm@NtLCU2*E+p^4wmqY+wbebB~OS zY|=Wfq9V@p;{&nIEe9gZTOywg*Os4Q1a9E`72bvA!{=UCrQTbB9D4uy-;0-zkB{56 zDBbtVUzz|EO8Oqz0YR4^oW%vI)=UPRTrf$>kNyV*7V-?VnFwWBMcuysjhlbW>%KNL zGea8QBb2$R6LT*RGPdJU2!!#1!1?w+nPi)hQULD@6jtl*`Avb&{(=6D)bYvbw87Oa zS5M}w^CCMh(cgh447bR?J1%d0q?Jed@6I-zZ~yvr0`lT}ttj^wV=9@eBo9T-j~}0G z+4*Rzt2cf7-nEa7qzrj&Wi{RC?fFlza$kg8Ody!t-}-E}A?fjtXzoF`K%yO^UbmQp9!teekeWi2Vn{qO*4Dsd0*%h-8@tBVl-f38XtKp}Wb=0s;VlB4`Bn0;6JYH?&@Rj|As+Tf6ekJ{2mrIBTFf$@fZ{ma_9(3{%qgN zbyN4nMSn5M$#Ht?ZIk%BM`k=Q5lErXtEY7nd!`!tZ#(dFu3=Lo+|k!}J97eKfTh(o zI=kg_xzPts938({v5*G3x*21Zg0MwPD2wF513$!D_bt(zBn=IM92^y3ubXMSJcpVE ziB^CX%+JmW^78(gn3h0W+uG9A)O-ue^}^a0FD?Y|mLcm)0Ad|#>uTkN_S#N(j%mx&x^zG#sXhGPC=_uj}#C|F1>b4es1C~s{W8XnsZRU}i zzP`TGt5=Y{&=nbD&HXftFltpk-TlAu;$e~OE-hkEFLB8|b66Df*7as2G`0|^5+G*1 zk5JUtziz{$g}-v&{m{Db??ifTj(=v9$yR)4NDR+ijn~`xxdz}~*PR~;^4G)5Z3lqa zE6`npDa>boSdBe-Stq*+&p;J_PPbFHkAmⅆ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�=zsnV7nlvPFG#Y1fxvi8|$&*+0Qo=h9&0o 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

!GDH#%tST9h4z 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 `K>k!K!Yx-WxG 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 literal 0 HcmV?d00001 diff --git a/resources/SineHarmonics.png b/resources/SineHarmonics.png new file mode 100644 index 0000000000000000000000000000000000000000..2b9c7efff5e6abab67f56637a5412c63b4697b03 GIT binary patch literal 31598 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 KX^pB~^#1|QtewFC literal 0 HcmV?d00001 diff --git a/resources/SineTop.png b/resources/SineTop.png new file mode 100644 index 0000000000000000000000000000000000000000..73528a0e3769ca8ce2309af34198ad184725996e GIT binary patch literal 78877 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

  • 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 literal 0 HcmV?d00001 diff --git a/resources/SquareTop.png b/resources/SquareTop.png new file mode 100644 index 0000000000000000000000000000000000000000..8553abb004b2b08ef2191eafd4dcf052dd355d24 GIT binary patch literal 72073 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

    hL!m=F0al(eLXgOZ@CP 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 E16=m+H2?qr literal 0 HcmV?d00001 diff --git a/resources/UpSpectrumSad.png b/resources/UpSpectrumSad.png new file mode 100644 index 0000000000000000000000000000000000000000..107ff195ec0c14cbfc3e012c0d54c19808f5c666 GIT binary patch literal 44196 zcmZU41yr29*7e|8C=SI6rMN?JcN-{D+}&kxiWFyX*8vI?Y4PIj?q1y8-Ql0U_kQ<& z-}+fuu$ak{JW2N1XXoSu{8>@@4eC2o008htRz^Yv0DyZB0Klvv!$LoqG|S2b0Nw*+ zB}COcAV)30NZr09W{+P#GU>2TZhDz>Cumh<$2wDUF7OFjDz;V9JDV*InTqH^oEf3q zUvL}J(z5VnD_JddLO%D9Hz1|H@%y?1V=_^a%j*%p^d^=$IZD47;jrM|jp^e+z=WeL znTS|GvOuxXHlyO~&xBpbSB{Hv_TL^t$ZG1QOJOXE-7TIQ5jalLa{1UiBp9Jx>yA8L zp}VhbQH4*Z%7pXZ_>_oXvy1ROhAryf%BW^tUgr!?$=p-#;oiTay^D;D6yRpp z=B=7;?f4owdA~2J>iAFp6z2kf@5C^B;kKS-$%O#H#fK1b>Er8yu7@glquJb%cvD+DjQyp@*41a^Ji4 z>%%#tyy%rhztns3Zw)+Sg1034Vp$^$<<0EMau_5$fV>Y^cuDsY(&Ro5`-L)AxKddH zo)_oBFV<#e!33bScK<1d?9O7LpT1t_8$ETazK`wll7x1+0cChKY96+Kdc9gOfYeU^ zn!`Vxmw>Y+=P^N_2V8`VWtP^vTff&^mK3=qzcoeljlm=atMt}8=)C7kcT9q-n1hM)jA+Ow!C%Otz1ZvfN(r zso(3P-(}tFkc00fG4_hS_qn7tp5)9gO-AZ`iMqtE8qN4dsQ)af8)0%XJ%Ckk+4C({ z@^`cx7cq6F_KSIoY@e6=-HQD!aQ*<3 z!YPMB)0Jic^e?uKxus`PnWvSN*McS==Tu5^Ek57=;#s#_Tn|&|7a3Ro9>m#HGr`Op z8ZPLxM;FDOI#=riFf;u)!;l;ICCuOQHcM98XY$-x^L!%rLYIxljgXXUID6?ac-kPq zjgr{k!i$QG6sdAU064Tgb9rh&!8KS@OzwRK^T5q#8a}7UOv=l4x4Y8vb@lmNiS}~P z!S6C5`)Nzb?;!!>&pRR_&-?8Z$$=)fV?Nh|>DA}u)%{=G-=XGl@$z_jIbP;h@0Lkb z7UO$;p2VP0Uma4MJQ=!DKk5ytOP^tuRCVt z!2-HgdIzn;$I@LLll}+UYQoPwEWR*+Exoh{An8HHzG+lvzdTZS^%fF9_;K~+B@k2S z8!!%C?Tp6<5l>QaU-*gpHCdoy>@{2X<#_eQE+KU8i0d3y`1xuI3YH8gA~z0&pZ=mf zvEb+DtZ^Ooyz7xOH~qWOb}oK+(x&$d8Go@XE&S~_kXt^8g2A5jLq!n8wt%bvhwbC% zZuTlWI!&?Vd$;p;|CDg(`{kqGqEne@SiQbnYtq1=j%C*GF@KR16)A!^UY#kG^veg2%;6m zC``Ld3wVH*a1oDq2Ej|K$m-nhUIPH!->D-N^`QDu@1m}a;V~dKNJ~Nn-DMWfX&v`U(OLgFV-(#t-p^Te{Py<(-Sy5-tbRw$gKCi zMy)u=BA%Zt8~0rJ#%D)^8=R3H7)!2Y*6XnCM@&@RX6(fwSk7F0cDC@it9M=gcOY!E z)!QSc!9}6)!ogFl@|NK3az0TLx= z^%v1|r(&(kTpC>^`Fb{2Ns&+-A9aomqk2?0FNj@q1NBS%W1nL+{)}zAf8Z-~>7>)t~QVIJBO1qCrjj zCW@GQkD>L1$b5w~Vx^JPoA-CQd=RO{9>c@3Hhy-1e(tO+|{rn z+L)SdL09x;EfBMNv=!?52wE!-vtRbJKP$n0OVRh*hkl6|t^^DCHYW5K*_=#e1(Cjn z+LN*s&3gANo7w^Vjb4+R&-IK3<#db6&$W+GcIk~GCV$;5A3k$S9HgeE4g+M(=$Fs2 z7_?mEkw5PR6X>UUZ$HjhyAFK_Y9vCvDaj$vRWt}LeuC{m)pIDu2x7tFBZ$}el~8qVt?GUfyLnY{!mHiK1ijvx7Xte+qPFvIRr}B>!o!o*pf48#DVW7 zA0GJfzbi?_<2?wf?ezEeLq||1$r9gsr~E}=Ec@lEFoJ-^co4kl;N)X-w(>D!HT3Bg!7#KJ+2Gt39N~u}Q`>!swBsD)XfS&#zUEY41p%ExgP#`xm zG1*Mg&=*BQ7Nt;sTKMaZ53~KaZblr|vuUE+zA)kozuawd0^1%A7{2w+XEmR#KBpj= zn3yECX_uCjmveKSM@2_ZuR|%#<8p+XO+21T_<3Im3UD7rJBH+9jPWBbx)O zO(xUyJ-pyB)!UX2!U)|Yl2&i`kYV)nt!>BV6X!k*eCUjOeOU8@Q)qe+eqDckYvD>+ zYsv&Dnj;tT=J7eQjHj9_*Uu9`l4qGabQKsN?b@nB71eF^+J^e|)u$b9hn2gY2$t4A zn$hq@Pi3&gK!*^0EvE9>tf zG9UxiAA8)a4939?c@|gV%z=pg zZbkLWQ^af=Ea$X&&FeSxWe8k)osuRmQ&%yRwg>&NYJBnBy!M6~NO5^$k19E#d3uF&m7xzNi|O!n(ps4xjJabOf5Li1(UyV}lv zu7fAFQnEl6*v7&czrDQAq<>}b9(ipta)*~uv=DW8@n=2~{Vnc@?bU-uZI00bTv`b; zto}jsjr)mRu>;UQn(rKaiX5+hw?H_Ta$x7bJ; zQu~gz*sUes-&$iOaNSWITB6<9x-szmDqRE|)w`m3>^^y@uM16m*FZ#aU_cwCCxI5H z-=Oy)e>%daoZbJaf`?H2cFbyg1y9150l@+f!vZgwM~nBZ_>p1HegpqM-Gm2!X??}@ zcSkt?^NZ+zTEX^Mio{^Xq~jH?EG>tXbsNV=3q+NQW=C#}IlJKtft8OrZ#%D6%tjg+ zfGVB$Ee(P){$=OCB$*v7nqK>LTX0ze-eeSUbF0 z51Ue-sN5j?q5vI^B?G`w{kUB#_=BSQ{hF`rOT2D*bMaehUV|E4?%~1lhQK6t7hM_d zw^?7u(x_y`KHgURVUFYaaP})xaA==tqxwrwN%-rbpZu#-FtQ!O=r7WLUMUTb`iFv~LQx^A&+>jd4!lo8b>o;t$^^C36@t!3Xs?1Z{72K}G7 zK=9QX<(T0$oy(n<7p~77*|~2 zR3%R~UcucxyyuLdjeA)E zQ#ZAad>X)Ph55_>Sqh@W@Xs4T4F$tudk-_$`-|f3uHTjT;X(M9)uUmpYn^qQyeHbg zrA+~i-v3TQa3E3xzcz&&Qt?-by3~3mw-cMsif z`oFKI+p$3Qzv`|3$KL+e`tUAD5@X=IZMnT<7@U6BbnR;Jo5T2JYH>aMdy<^;o?A?Z zm%-v1{WmBQe)}SyL^_*wxudD?F~T_U|Deq=acFyc+bk~iS}1Ka_Ifho30(^;m@`c$ zfN1k|?O$Mu74I{28Y_6z;E%v|@iz}CDTcjw5m_{;@ItrvbObfuf6>d|-@i+^!q5Q8~3n8IIWavW} zP_EF{&q&A#BrGYB<2MO*L@4h27p-oWbguuqP)d|@0cwlIoPrr?7T@w~I+Y3ji!?!h z`S@Q&P(sQ0mzPJg7*d1}g?tc{THka#D@}0*7Xk)ia!8D1IfU1c)e+@81U=b>O@3O7ZZ}N_*ag?zf(ybUe zMmP~(emdVYDZ@!XI69HF)=@&SvYZKt$%Cp;L#t4wAtjvkF*DC`Z}_ZHhp5WsaWfK% zWW$FAGPHc>eD$R}`j-%_=$>3YJGAbSspO4LUCl`03Cv{VDn3HV=%*9%=`~vX2wwI`^B%!?d!E}TZEM)q z+WgK$DwHviIcnJeyRDB~j*3K`yhynjaZ_!|yZ@csPAnP*X^zIv??ApjO(k{t0ZFfm z4(9!G)7ewzj_O*SN;WRmyUC@jc4h}E4+fv3W{wXkBJ?^?L;e{lbg+L5gXZz~L-J0$ zJD5?YLT&0Di+)grc5L&OQm%K39pOCtXGA}o$QHS$3I35^(q(=T*Hda3;7hwwv<)4%^ z{$qw%zr$yn!pGIuN*4V8!AuCO;BA>p+P|Lvmyw)9Dd(&V`G-kEz>EpcKT6?$fj-m7 z>SyljlqX^*&}6l>*N;-!VrcB!-X`0dXDJICoI=Hp3w8mIac90aSFSy#AZ&GYz6MAB zIVV19A{1D=PaJS_<+m9__>{U}xc`iO!}Q~O%7omWRv(em{`G7f{iI+nT*j-!y31AH zY5t;GbpATuYGaG)+qCDD4~Rl9<*$dYQWvMJVjgNS%V^~#6!QtDkuk1Lv>Q8y=DfkKiqa zCMhp=B2b<>At8rPPS`fMX6l!X@96!#|A2OV_^-Ggfo}Chzh?QMyq0>;_{YEg#`3?O zQn2sJ1^lvDE61;czx9`2J8AfNir1kEG(0vbdus*%U(nnzoe})q{p$s+X}oB7$M%Nz z&j6dIbaeaiB9Kn2QyeqK-um`-rynbDCho&$`i`X~b<{!0U@_HN?Kflsv4i7VREa|s z%}dj{LeHoxtxPt3wa8hUo2=a2tO!Hss$HaT)Y=P!M`(c5>=bhcw4x$2y_NWxpQ?`M zxr~n1sAc+5htqX-Jk(5L*_i)vmEVYrlgPb#+VHX;`w|{Cm%nPTPGhK7S6Ntmn*P6@ zgk!5-Vn<^g{QPZSV_zaJemm;TIkwS|@)z2E9^z6yKzrN=Rw1%qk{&o+kUCt!PA(>F44lpbmplU3%>vw zht@L&VJl|FgLixtO0kUJCN(hNOxKG!g>~6R)7el20l0WkhK8gRu|$J;_ZO1K#*^^0 z3S@h$i8TjT<36N?vnY$1Do?`x8IB~yB&d&@WmKi9z5dFn-3P>CrQg!6yS@+A%9}^Fp`2bPV%PXTxLj3X-Bi;H z(9j0vtC+%b8!^aFTDW*MyLmsj{MSG8V?MiW@~KrETrX3afw1jY66X~&10HV!u}6kr zA|=wDE|jm&a@b@amQURRL8s7a1k67KDnDDMw-#m;&GpgtOjpy=C`ph*A3j;-7Ld2A z6N3pd;N(RKh9wbRNz^Rvcz$I4^szh>62zd9j@{Qsyx0dn-YJ6_M}?C0IiC(}u3sOk z-;}IhKVD7WSfA>BpTDjhw+w&(7K)jCd8yo1Z*ScLPrzptZnTr1Ps^w2v^fh`hXzB# zs;Xx_1RyCMA!eq?cf)BMK=2;|dHLVNEUmFV%EcWG&KDp7Wd)jKxi=l)szyJ9=o{^k z3Y{E)`$_ve7fd2jBphX&nw(A_4(>`cp7Ao%D)FE^^~X|cl>1Ip+7_0@y| z(YS${$|f19ggEp)nfw5H>w_g;9w)H_cuR#ikK=_u>s{>UNAt@TV_aY)S^~Y+=FuuV z)X(L_vpi15B`R^w4>ohAip{!*Dz_(5Of1|V6%{+P1Vh-a|FoNjPmGR?Np?!~H zvY{&0&tX1l@cQoNlpJRa$JsECtw($ZIx`$Nu8SkmCp9)EF=PWYZY@H!ey^#7$JdQV z@3%Z}N+#Nj>qm#%=c^_=FE1VM&Qg(^GqOXgEb@cLApR2*Qk0cmcW?i;DK|V-$jZh> zjhpA?bNhF2Jtxb=i_jN8;cLseYYn>aQugexbb8{O5KFL0t=mac_H(+rz!5SKYax=_R0gk{PeD`oL~w5 zuTccd6lC&`6_w-nAANSPpl9so2nl#3q{ zwnKLwo3z$hG7M%xVc1>)7GD@oM9W`5Me0`jpLnad)yMyGLgTN#hJgfL>rN;gA9 z6*{2Z%a$S%u-G%fuC!$6wxVxtwre1st^n}~%$8Jg0OhTXzUu)cdsq9eY;=AXRHbT$ zV`KoCBHkoah;Z9z54~;w_Rygh4y6F=%}*xAehA>Kmze$hWcgaIr(Rc0jkbNJ_}e>* zYspeXG_=X1goLy0l*93*z=VW~M*3oA+(>PQ(U&qMjRS3=#u_ukY~Yo*xzvP-70rw|Fs-fL_h7jt*V_|5K~rQtClizBgD>~7 z9TNUCU*<^$2bMPn1`t1H*@3XRxMr_So+dub+x#KO<%RNmFY%#RORvOpx9|P7Yodx} z^_=zD#n8n?%_oojeAmQw6zBl9SY9^3SlP?F21HWBhN zjdYtjDlVRU2k33@l_-7M$4Ji(?U78o+yRm)_HgwVE(g=ei=z9wymMgf`o^!^ zY;C#1(1-oVF-U)l^M}53`o%svIDy$cA2>Q#$uWL|O(6%{S;d_6jt>T@6-xM3~JJ&?-)c4bM+c7D73^RlX+GscQ!H3F|?#e9fd~SC6sEQ!UjZHtb#JQU7*#o zMHLytU3-UBQ1JaTYpMo)$ft380Xai!)X{7ttj=KbIaKMK_fcB3BKgK77e5T}LV1B< z;j^=bW|9k@oAxkDGfw>%%JApA+c#1r$#Rc=)uLKoqhz@D* zDE-1u>g$WLfw8SJXk)hf-T1JzA-U=L{=q*cKdr4lS0O=37(<9e1^v7jw4wVoIw9!; ziPMcCH2Mk+-NdbnKtiC~N+|7pFt0u~%;dL#1VnKt`qzA__gPF8Uv0JXsMlgy;CMD0 zmaT$xg}U1aYail&rzWc4y&q>5P=v49GMVjMj4q5k=F8nmS=!Vel~#$h~g@w{CK|k z+gc5pOjE!sXyxz(N>qmVapC?V5T+Nj4Q)b75^D60Gwk#jzJhNuv+F{WePKQVQ^0sH zKgFSu%IhTv8y!Kr$%BSERKf+1a7{Lo#5h5{WMea- zRH8AQ(mCsdmBx>u3|Z1e*~dHLh%5y7y*+PWTACeqBA<=Hi*;{y3KqKaI^OaXpmOz9 zShx2R6EB{1LRxd}5YPzRuhkUFf9B!XNr_tZ>C#YMd57s+NV%^qHz`%4l^0?_ zk^g4q_gh=3*f3evQN3t#huold*x61S0(f{BrSd3qzSe`(-;~jwK#|&O>ny27#J)S| zOO0lAYJ>?~lAzQ}G02tU#WY`zjv<*owUvx{AsSkSh>s*16|CmO62vrm>wdea^x%w? z>N3iKv**U>2rWB9MHd%okONlNal2;EGNz`cw+Ls8?j%%-Uy<2$DJFHn{EaPBW30-M z=d5)UEA>Q@*nH1K+2idJFHwe!fNQQgj&dYtkMc6D58B?2h*WdpPiK?e^eK0o4F;05 z2gDNf;s;Mk<~|9EY2~e`+6=<3B-EwGkJot9)!m!O+al95wCA%-AM{a6u`bf(RVPP1 zYcsGak&SDhOs0{7Cs&*kY^3%QR1$1q4CW6LW4gDL=Kb6a-uM+A7AlU0)`Ab0CE?7f zFv1yk*U~Ovt_VXCRFH1@PHs!03N6)NYo|(2m@E{Rsi!KrF`YqEFk}ow^8794=I@bG zxSMXz0DUK!%N3rkn2z=@(`UL?%IX|LqcHM^Uqw_#a+R7TGqplfZ9HZYp&H&gKRNT) z1jM(fl+t#)M?$>mrD|egxVI&;QgKwrVW1EQ?o?L{&seY7T#~Fto1va0V$gUlD@-;|2TEI;N!HW)M)%|58He5A%xDs5b~3N^HWf4fVCNrf(t#vGJv- zb5HN!KNh!nyn<{DT>|=L*HumZo>FFCJY&jBVMv=I_dPlX<30d+hqgoN1L)}rOon4m zR=2lH!SAoJ6iq!9m#zzRf}Z;y1KeCL*xAyht1ET6j?`&wkCQh9`uaq#-f5>IVM4W7 za4?N=b;3m`j*8212aNGUkH9{RCXW*p6GW#H|bY)m;-WUf5Fx+a?l4d(b zXMZ@YmvC)X#2+3g!7Kj}D*3Ztwb<`3vm>ZZF3zbRV0lyID%>5CCY_$X?@^XeXpiL4 zOQvn`MzZ=LfU*QSM|0=8FUh%XEf3kRN#6kOI5)>QQ3rAJGR2towU0irEwCYsF!M~6 zBXznk{n~&Mc=Wpsb)! zzFXQu?TI1U5W!}jt?{H>5JodVybXy5-H{OR9n}#XuoB1%@Fm}#kpVc4i}aT@G*W4OnxlB%@cz~&cUI3)ez)t1l_4S!)Ic$Q|D$$7XwO)8-jRVsPeocE}1mK79MHKTj=WvJqBHj z&ZjF1LX;NK!TePjZmMD>6EP49{FM;M>a)GMV%$aMDIxFW@!R->n9%haN8cAm8<%Vj zhL6G)PxvRRmZvE7Rq-D&dJq##D*`{YV7~fYQj_q{rn1F;hyimublzX;P+&p#)i&k+ zJTo{-h22l^jk?s)LahyzF*GX;aHq|1s;W9UTz_}YBqV(BmzO}Ws;c9Ksp|2by+JcA z4$RuabwT(2z0`1mOt%cdD30^2^=D>>8Q*=C54K?j(Hf)z$lL6?wjPdWXB5p>*dzk= z^SSwbtSw{1U@$byc6X;vnXEJe)7}wSQ4P=1GHn`F(%Q~0NvZ$mcOV8?5QoLqwsf?} zPk3i%AUGl6&E|WgU-_TEC442j9N0VGjB*CwVGA)mMIciw{hP*R3AB!mA@<)rJz{FCDDH(zEgb80d zQo3vK_O{d?a@Wr_+Ml>@)4ul6#w(?g0!Fh_I`qH8ejcVRg1j-Kuu$KYAW6q_TDw;n zw{;`6KmlA{Mp@D*?%z2DV(X1M=aSHdt(Tc5Xy$khG0|=0Qhw%NC{p2TBKf{QAjKMp zHWHP*L;Z>4D$0g}bK#R?43{aq7YJv$&EX7^&fdu_JC9cf5K@v6gKp7+M^y79WQq{E zsY}hreFkyj^nb!jN81W^bh_(je1)rAe_$egxQP9V^v9AQM%S*6!=iCnvMB$%(Rn4O z0Ag_;^c(|v$Q-TTCH+{@Wrv4BemusmjmY%|Yhgvwax~QPA_wO>8l|G(l#hlbX!l2+ z`WZ$yhYUPzmK5t8m~aGcM2H7?CEolMy)G9rW1Z9u=gTW;ekS4U9E%b!=&}===Q`p^ zg$c9%-6#EuM$9%GeJLI#**uU&K(tq#>wo30MlrTKcZE2D;?_#M*c%{Ub6AgbP`0a)Aq@!A!s(alP;JwplfP(AF~+Z@`~q<36SxSy_|}4hBI1>ozSI z8c;Ur9vEah3Uky|hBSSEw}++zSV4sYFQq@x*2+K=a)*kO3nftKPNh+(E6^0vIi9Lh z?rxHO6tqXr7Bg)&nK&)*MUv;DUW9okuE2nWdUnQoCUU*KA(6)qp?os*(t1yeG1KbD zHW7d}DSgynB0;`U_ZyX<{`+^*3g2s>5rQ}>e@RwkCW#1d7Z7$#MuEDe*9qK^vaeX{Mf-T~g@zyc3IM3j#BQv2Cn80-cZpT!Ac?nlysuv4kHp|j407{G* zWhLmNbhLVlo53BU-j=6o( zXA#IIy`s8PryVpg#}2BbrH3sSJ96oQvrx}2B^}*T3-;H$_UEhUK2Abb(0kd%-y(CW zN{=hz982VdKr_#}CFGc~deQ-x2@>$K=>`2nM$AkmIJCPpHgq)Jo4s!a4QNf(6Q>kl zfgda>Ev0PYmM1y47ipj|5h_n{3^H3PXk40^rE4JJO?*F2KD#XeQF!^3s@tt0k`M*aO5s6Dj-d2}Bt+8N{FJY#j$ z-{Lv2N8i+ph!-l*^+c9z^k+}iK_bI>TQvIyz_XNcd^E0QSwAE0@JLg8Hj#BuAwR<7 z=6mL!kx_H8Z+{YfGv<@Ep+^_fu~9RX@u;2kJ=w&~d5qCQaWETM zoU_LPHZ2p8YxkQ2{%p|5pHKRvY;&02Q>kN&4@HJRg&(rQX89!`ah0HvNl*a zJ|m&us3p0pKU>!K7=oE0ykPIG#+o3Er~rV?=dUB+IJ(#^rRKXWB_+GyTI*5wPyG^< zwX#raiQ1@?Fi#{FnPL(_P2NcmZgU_4i$N}rF_W2l@ECo0qui>dfI{XG)yzFL&JXR< z{G^M$G!F&7wkq0HD@cIZURn+kX+Qb#CS)u~GZCi6puf3fb;x@zgTtZyXfASg2u-F& zA^E7lc*2%QRs!W@_qKT~$y`H^<(S4pP7*wx&;pP&4BHbu`A!cf_!7NQfo-7@Ehzqn zH2<-~c1-mBeJ>IjrZhf2)wSZEr?BeePKq~Vs_Cxn(W{d67E0*_BHFlv+MKk&?*#ef zopWuDIbk4BGxV^G+x`at1wbMMsZH#7Kw>5-D|1scF{aE+jRnV$eY{(M_!qm6A$uFl z{M*GxXZqjZGLorx<}4qdJ89}FOmen3QV2Tbo)ZtJYz-joE&{IM%hVS^!@(B7DiVn9 z$$WweBUVyZ%9%{Y1XT23rHqjYS~D{4geIN!NNBqadoib8>NyugZ$tN+)j8{i0LY~Wmn;yci%~S zh-4_1%v=;$dNaJmWSCH`4yegX2y~MJWquPnn-?b6_Ht(;KZbWE{%&=X%%6e0amN4+N%d^uSC#;V$P;r-tYE+1?@%Rx<$9f4j+b{{n-|-QB)VZfn(gp4sg{6DeGY9nV zi^8t*lnimg3F^>8@5^x}48#glY_lE6vBV;itD(lH$-dpDC@h_p6aFRC4x#P_qluX%gOf!9rb94Ii>SJNsuMbf; z`wW>FIrq-HnID4(we;Oci%-vr5{*KkG$yn_$`5D9f_1>F9@Rn~#WFZ+9ZNN^KZRmI zJWE?KH@R<#eUf@fuz*mK zNJP4+HsbJuT@;PWHpN_`_>{9xA+8wezH6lZ(KqXBSfNkaBMI2|7>s;)k$r|UC8`}^ z#KK#2!aqv3G3Zp$I(D)<3v8!oTZ8J;kzL zf=Ifm#dTQ;Qf$t`qsf--;-youLa9AlBVt=e$e{;dOg9@?zs1D%2lDV3$vTEp2rja_ zNVG3^kdlItl+Bo~1$;@gJEKGYE03LZq4`AJ1N4gjB>lm*Y(Hs1twQ~!7Q=ESL+SxF z`*nhd!wWPIk|s=Yei3Nj@eW`?u_0fAP@R7Rr~)`EFkDux*5Z9!{NTc{em z()hkQUm)w(QJ6#C(8E3FimMatOOXDjsGDSe+ye6tpbfrge3`p#H7xSuW=AF@5LODd zrzxI44anY-fth>3yK2!6>=( zy^&7!1a`V#Uex?lm&ZMocE;8niwJ!-&?Pk*@xj_MD(FzzVoPv+LtlUxvikhCfSi%d^hYY$U zgR2&%D_J$^6g*5U4uYn4nMIpFxwqz-`ZZNNGl;;^k+Pq$+_k`Sjw3506J{je67YGcuWeWAs zi}UlFSfmeTr*dI#482H&0#tDSBZ6L=-B98WmF&@t-7cdcT z=!Z*8Kic#vBWtWA=Vz}e_~#Bd=>EPS3o2Cpp0x~Zd*du+U$^z`j~UF{}tiUTO3C6Je40U6~OdIPvlIiOcfDhtx&>0}}hNq9s%)y`b)` zcStwg^UFLB`O)6z{Z@%WBV>1oku$2_Gh&Ib6z*{t|p$bQ{8Skc1qM3{FLT>U6&O)pBo#GB9x@kx>9N*otfUf`gxBFA z?{?2tXv1HpQlVFEkEOn{C<=stLxRDJuE|qdZj-+zs#&-HMj4}q{C5Qy9s{hmcz@n3 z{)xQ>#GYZRrOlfe*wPR5aXqHEp|4|*Vtp0;E&!--FBecsGx%t{W?fT|Xk7zM>ES9c zBUBcR^S(+uz0V!%eq#aJ;P4rmKY--6e5Wi1)YfBN%1I6i&sbj{%#>d2>!4d>&3>14 z##j0kXKdhNpjJFHFi`q#KpmQlFQl4Axg~##5wnvc7{ByFc_*c#@F(1_fS0?D!e>ZF z^tG%+q=E6P-|0#z$U}GTj%TTLd76^>R)xXw=5s$pc!!TfRHsOgox96dDpAb9R2y$!Xr*k2|~Oo;&_6 zxW>x%thlIe|2e){N@(F{@2R&%@so;Gaba(tky-vZZZ4>|kNA*^MzPvY&IrE$wv5lQ z4fOWN5C|1=@+q~^>usJm(WG$DX>9niLda@A-b#~XTLc-X3fQGq`dTAe45I-IYDg9XaApEfFusvex6UM zG~oc;H_nTh%p86i(G8hz(gX28idNXl_E!{rM^Ad^I|Vt=bS=lb9ifMIxX*VriT51bHd~Dynpshh@uNMhf~iyeNO)F4f}kQ2u5Je7vT{LBgo9#IA%+g?;`V_irSBy$i4Ua zyt^Kq(VSNoFtorR@#%nwrUh|S;DwmIKMQI4YREGi1<8tyJT3=Mtw1}--a~q;3E?UP$sv;&7jWBZ^_2TZs z13Gu26@@BvRzC5?#kj3B>|{__qG#y1k1P)A9|xC_nhLwD1iTb}?3=s(_8k@Tms#c6MsoQAxNK<G%J-($4$x7dwB25 z>KurB*E!C@-Id_y6n4z-gQ(1$!nerBIEzZ*jq&G7hi#0R%-gEZZb@u+8HSgua+*)>XYzCj^ z+24VJTTVGZaHYH@R< zy`|vHBDS!8NgtbpcrMwB z{L&LRJfvR@kF6+Qq+9p#Q)Sswr>FDLZFM;Ce9i)hkS?0*K;c7E2w*Xjj8*ZO|O3(UG2a| zc8mD~>2%pDK7K-MzV0m_Jd@%Aw<0>3(oa>Nowb{j3e}%O60hZK*8~Pvn}B3z<*4tT z1Y=`F@;SV1&bRFXAVK*(ja!k9_Ubo-POI1v*eIvW|K8zONAT~Zwqo4%S^B8A)G2tx zm}+7}vdsTXr6M}E4Bq22~et zehow{Qb&>v4fA>IPFV8$ahF!vmetW=#KnyrP5>XW%~`7H)+@G{Bj%a|t6fQ8Q9#&c zN4+m;o0@=xtIaF!pPOC4+p=^gPZzii4L=(oJxnSz<52PV=6JnMQ8pg9C|e&jr?t7C zp?l&+#YNCn^}ca@k5enjUIJ4o#X6HVQS{EOOlLrOcYca{n}qg&up2qKr3-J7_pSR| zyC&0a@q%dL&yZ3RxX+1nufiiVITaPL!fBvU-8&ct&?h->Y{9GwKe zasuApZ0MhSH(HzK!-)1+YB@w>*D3pN1B0@fsPUxoLo6M z8kq$TQ;OXinNN1E9J)F-h+;!Px!UbeOr-NW3IkxKfCM?u^LNYBG92XL6jj}`?JRX0 z8Sc14P`%-Y#1c^XNNg%~5!}#1Id)YZSt4`$oE_UksS1q$Ej{MJX*+pQ+N?xD`3VFo zhuYOJR+-*YXk=|otMq6Vnn`9l-jM6z`>a=0MrTRKYAlL9V_HCc2H_XjrEEkXgX(rf z%Zbid64S%aILR%zs%RhHvX-$raae|`8?9EUT5rpzPJC!JgBeafm=&Pp{LPgsDvE(L z>y={wK4gbs4-u~F3u7-^b3{klfc;#FA*_{ZGv0B@-I@!~W*G#wnXv9k-fBWdU{`XB zicfhjnN4@)dLU}i&LK;6pxWdiK^Z)1(T)BVVf08|rHt4HUd2jME2UQ9wYu5F!o+Rc zC;Atm{+Up8+Sc$>YMaQ|50Vw1rm5aqy9%h?pff{Z2*P#`k&+P ziEA>DKOjyH6xijYY_ zYYFObyo^Z+cLB-ZoLDiXQpoARk@DNSvA2)wNKJ)d89&U5wQ!K(N+{KhG2Ne@5qkrg zGUfF3r9os>(a=qk1k4b$4bBz}bw%o{NCZ+*c*3UNp?>%jQICxvLshMvM8aN52?LvN zg>rC!cdP8>*VB8Ww69CgwmXiuCF<}BEIMrjCJ zL>xT!`*5$lUW)A38%A<`_Fy8$J^CiZ!P{I@x}KiizwzLB^byUDaMfzO+X_W%dQPz= z=bCEZvj)+MSk4!#V`U`6mgocVu&l3Tz8U)R*ZRiLglmk!#Blj@Cf~9h2`?*_iOHAG zkHn93rO0q=GUk*FDM#GP5uK>t|7K<7rJ0^~auv^fU9YDjgNN5z_Z5o3Ik7q+FC8P1 znW{ueGPt-FnyPf*&DJHW7X~G`eD8yBK9>(7(1~nj`JY)qBf_0N?GL-!3902RvY-4& zC6hV?UdZ*wQ?NGvq+P978@q2YZkd()A)iNQU0C5H=4BjNL6Jvm%7@os6WDm#9ZdMM zXoQO@b^TkMHaU+_b=L)K5LT&W9S*(-uDSdE?3 z=71`4{kD&A3Jh?9alL(sL#cW<)hKfVW=i!eLVO6BtYh^*DAvN&#(e0gmK{8bp{^&R zd=Zm<@e*ylzP=M~!8KJ@S5LriJGHG)F>R=*A*9<5tVAdR89W{-qB$zypogz=>?M*Mzz&WVQnp{kZdPKZcRjnQ+Q{t+sYB`)U|LDV?JjKIswGv2~WDV+_&C;U{zAC)KaC~GOe15>ol7Cgko!cv7 z@g&Xy(t2C-j6O(0sA5 z16ke}^g6i|axk~jT8`-vJ$(-_54}5@%D}eeYD5;Dnc<@`%ideO0~4@~j|Ia?%DdyJ z6rtFDPP=c3QLJAZICL{dc}+7+JUBYLF~_hc!J~X5#Vfe{3Dz7kSspG!EvpZt+o(QD zPz0I7bKxx!XA2$Qokd1Wc~i`ym)aygQiV2oFP!U|n)=N+Xfa4+aHIbh;+kMLz;4A>k76hD<7oA7sUSHVni| z1kKIpzQLPt^w5f}v~#Jck?P?VsNoq2hbKkc6vJ87m6fh#)g+A)vRw`GBa;eV?u z&V;O8Z$(N?MeFDRi&=1(emir|(gj6Bj!>Mmag5fIGCy4x6)<)7Tpp3H5jIdXbJ zJ0!N(D(tdb8?ytO2AH>7Z#mXlu-@7gpS*TAv8OqDeiX_NFfZu{1_kqhK}1udAa&zi z`ph@g*qxLV#AexG5Ich;9dhcLM4uTplEr;ZG>1{)%cEfMmQRjh_nOSXfvn2%JGW#< zFA~>LHa_w8l>ere5U;jJTx_`aBIU_tt4XGZY5D3xF|H9vQM8T z^`_9^Im<;NLWSp!WB6HSu>);*F&#B9xysd$c4BG*?T}fG(gx;#@J~+h(3p)z_)y?{ z%M~~OPQct<3fIEAaPF76+8-8)=kt@-pp*Kp$$VsII*-;eH1RdELHY5MT>siM{OTJP zPgSCiPO(5CR<)$ycN2BF?1D@X!%Muj2BWMwrEm9#3XRlIWF%^_380eH|AF^#h{P!1 zfu=qVA?vFw$U(_*3KWRw#v2jShZbm@+(QZPRY^@FyN0pG`KewbG&_43O|aG^CNRgZ zIrkMks6@j-tt1Z;&>XkI} zAkM-V4`rL$Zk+!(cy)$0KZD)u@-8oo2gI;Ch?d=ukx`c9~=I4kg%bm=ZdIK{0CM24!(pq@Sh_GI_4 z?-9u^_~Rc(shO_V7`VgTGUR~j69-}O$^-}lLTt+Wd7?vLDmV;SCw}7aTCyw*WEIR` zD^oLkBX?y<@+j(=?bfPxM8fLyax%5iisOKzGK5H4&}?K#(lK5eVGF5x6hYyPgFveo zxIRiw!P5xXP2c>&AB8yT_a4RFVvPoSFue8`f?gJ}KoOJ?r|kk1ZasHPT7$ky25}h5 zTpHt_ZA5)$edGf6-)I&y`WYl~Tss_hrjaK2HOJBMwgOemgHFY45YJ)-(q`&!JpJMJ z#~#KzCwu$q=L*ccqU&QJ?*vWGX>AlQjrHw?M17T>Ju$qf z>~GP<4-DV6hkClrnERlk{UY5Fem^z#xo8`PxnCAa$L?bdR1H+0zY9vM8*dO{hDqY# zr|1}Lm()WcB&eu2hkaN^cRyw?U!lPeM^RAY?Hdb@3POisZ~M*B zwvG&?(D!+}js633fa-%}Q-rbqJY+a*fr@i$I z))n8F56-LI+pqX1oSw2AGA#CYb~IeBaJ2tP)~?G9VM}lb#ku?zAr@Fn;|Bp1&izH= zEO!W0vmQS`=0~M3y31&xMlwI zdhGsia-bJ$Akd;o&KZ1GODh6}I=xq;!G)PXg*8Vs;N$~p zgZ~a*|LyZKCt@UMM9&-#5G{z*Z{dh;4#sHZDx!8zXP(_q;P(*tZn78~ukr*FBm}&0 zd6Phg%apQ0P5Jsi=1Y%Ajr~xT5=DbX8zWWnIHKQ4PiLnX;Vg*bW^-U`*TG75YA_BT z;>b|6=97r_w0I%{U9s6*`dzLuz8wy*R=CJ6-!_)s2_i1~Nd`!jLTlHJA{MF1!polc zFpQ#JV{!8+N)4;0Ql?a4fQYJIy@Xag1e%sBsq>6GP6ceCaCL7**| zkM5z}6xirApl=l|@tDGvr=b!-k~AQZj;@1mgAh7dIyE08Q0~~^#~khI9HnIYtM+E1!ZZnej7druy0~$N$UQ;#0NkS8X*6Y1|b%`H@U$Vi(JGbArl!PX{W-jt# zC)mwYlNeA#u_bweDBWwho(J3Z1wu7V>Yr&FyCtu#>*$>Rr7U?GXx^UGk#EsE7 zu`y;IstQ=od=qgW<~Nf|o~%0A0GYoeAQMN~@{!6*@cVnUDGjOjPhvaWO1K0W<-^oj zgCpYIf7|o?BxdHY9GVlUQ|dD|%J`KyhdYuq0T!#F`EK^Se_jyR0;xQXiS>X`vC~At zSoiteqjw;T+=$*03`=zX##|JSL}j5mE&K|1By^2g zh{uv(;Zv|LWn=MvsDyhT(M9L39&to`h#^ENbwLoj`b(8BF%F5&Oh}SzgL5KZ2+-br z_$$<0=Uh(2V-zEId5LH_HthNqHQJwm$KCaTq8ZDaw7U$wD=Pk1q)@m#bxt=e>+&1; zeonz2TD9ir+&rnDcV{ZBZ%Pc?PHNkTpecg$cba4_(-!SGUW^b;;%$HMT8J5UGlh&K zwY@Bes84GX3Cv9%Aun--kg!jz^0wDP7wy+jy$et4(*-?+6@BYB{_S^xAZoMCa0b^- z6|to`s(nGZ*bjj6u9V4y^$?iI3(K|`laQnGi(_PwhKEkVB2HY$(ZB}ZIg?1j+;o+2 z*bl^%MTT(jc$3!VvC{6x6<^h8!ML*GJ2Q;b>Z??)H0hw$4kb_1(VsFf=W$KLpnJNz z;1?|+rhG&sX%BcrLU)CE-vKgLa?U?UL|qOHF*ObSWNRusqGu4`b`(EXp*EJ^^O{MM zkrS;%uQn${S0ety;y9UCc*dpD}mJ{XHRV9PC z<2+UgXe%Sr6zC%6kECPzCJokrCB&lg>MWDcpF#AIj+4O`sz6z^!6%V;CBEk&pwa3B zHU6VLAcP7ED8g4)mm)93>*e?w{k}$}dkItCuNh`^;b(Fae>^JNjM}PVtvpa2LUkZ0 zfMnyfiN8m4?bE@JO>8__RnX~E?$UsKDJ{G5`Uu#W#0h}!~9jo zpsq-K{6zVt8;8<$CV%tE?b8F#V=mt-4V4a`(VY&^_wlw^l-6s|3h2pVR=oIuAQn=BKXRB3kuHMH32r z5cum2 zGhSX%=K~>6*JN~YIRxalFvH&>@6zs=6M96zoL}5KK5lDdlM&X^75asA zo|}X_LTRT7?D8iRalJ2Wa=V4u3ge(!>?b1BMX(W=jKO+rP)-|F7L{AT!T!w1N&CGJ z0m|p@i|2boGq^wti(gl}Weny;P)$voDdPt+3%6gimtDI-mK7Qzif|6JM@6OF%u`nWYB7YVz8k)z#C%|2 zMi>Fg*!?xk+tTm5LqkrCAJ(ER=LG_5;hUPypj>WG@E-M0fyQPsAsIl7DT8;#^eO{< z?#~IhyV8NaZV?WOZUx8tblmm;-$2j17?}XzriH#mLt24W?K1&|i#e)noyxw=uCq)w zzVwbyD8M!S*z(Z^e9l;O3=NkXNcJM$f3a&(3la7o9#U0qYEr&k)%(-1K9dgsnC}u2 zJR9~e6ZrC@M^nXKrAkP3;3EI&hL%oByr$=aYWLSp1TLyaf$hQaWio_b`EP z>CUDg&k(=JxrOLYPkc!W&>p_`rTS0fxJMe7nI939SIkNx*)tSW58ft+FslFkIiB_V zUpoj;j8KxI%8-P@Z-v^%j?~{P(msC%W}%o(slW)qGiU{9RBva=G51=6uxn96AQ0BI z=#spekQyy5sGYMC>0DT>pl7~UWN?1XVQWcVCm2uxwdeP+i#M>@Hz7bs$#MPcy9%D0 z<8XZhzUj{doZBd<3ev_}3wo6jtWZ$_{~IRQY8p9t%~k$_I}7x$tbbMqHukfCrwMdD zCvb46VPoaZCShToe8CTXRcN+s6nKYJ@hfKSJo)Dt!*ubW1V)xlT zls{~ZNxm(1EKh{pJ~WP>SCnVukzR8T-k4}w-{)HBWW@?vh&zLW^%%QjXUe!0eXSD0 z5I!8|hb4o5McU9_XJ-Sz2etPfSDt&S0LcO}e$OGY06@ko`M_MfK?gP%U5}kosJ(;W zaDBDd@~|YZ0`s^%mQ0A5glg$@<|;32Z$PPG(e%}i!R?GB9uN{2SMKX!`6Ldw-#FEy z2n(dK9Ej$+Cz zq|vLwKff)#w)ZSKf#Hjbbo!xnJfQV^>k|W?f@yy85VL~P_*#<`CMtW-#b8ts$TORZ zi&GL!+_lUB+;V*%$wbq4U=AH(t3u6bZQWq2z~Qx@6(*=! z%VSk}1|cp^Kv8N_6Ovrb#)o#VsVhb+YwRi_ph&HyTgyUY$NB177eWmzk)c>xibnVuUQZro)14AOWY8&c*tr&P(o?C&fbQ@1WS|P& z1Hp^{BL^snmbcPX&SH&%k3w{R_5N%b7~9p}WLFgBQQ2+XSxxKid1~| znrv)z*?DnQup=tea{c;^^OVprjR$m_^F%ZrR8}t6$Hq#A{V%re?nS9@CA(W+qn9n8 zKGjAfZ|)1^P7|UvLlBuLn&P(K7^c`xvNB}jUbhoY%N=u9qbZ|AwSy%iJ>5WJ;Rv4S zpAgK&F)2RIDCQqjdHB`r559!$e`2(H5z8TR7TB(_jOj>LU( znnVyqCKh#Dj%(f=apBw;Hf^QjW@X#XM?GEmMqA~JbhjijR1NE*mARuzmA@5i7QCrz z_EBM-2;?h^Snq8LWi2Rht`fGFiaw4%%S?-LufW`03nN`=&s7-Z(yeJ0$)VALtHRNB zoHNt^v8emt^Dx@r0(STN7uAwtSkQ;hlvUuW4rBe?9P_Csj-BzUw4sJaBJUk@1*Q** zmIfml-KS2w5fh5Xe0m)X+e}HxP=0fwe;~L1zIL6gkgahLAdR=&5|sISuuAB!)Zo+L zag>vht9W8Kv!1p%$G z7tH0>&8*WR+WEsn4T_*z*6xWwUEM&Vp-8u;cc*IZQ#c|69P~1+nNbly+JgyU(n0+H z0M4xq%+IGjf|zJNzD3KkIXZvus3j0cnnV7e#^7Q6<(}NWUMswpZ+247d2Gn0{34^? zEkvKwU*tE^Tv^mVSPIwzjrJ##68RMBCt8)9Dd@b7KouFd@{L z+!6fm2h*IHLoX=XemkQ;Z3T)L+%?(kaRi47yUc8+iNjBihpRx|I*xHC;gB)c8Iviv z%=12&n7r91)4m31vwxwdcf@7hlB5dO-?Sf;-h5%rz!#*iLPdBje0cGkxhzPJ7G`&O zzufo>F9`3+1L5}sCJfo{<==O~RF7@)CwE<~v+pd@Sxx=?h-|NB!1<#N8Q7oVW_M2z z;2Q~4(&df?B|9qQd%dQ&liJ*R5^W>!vW>T62 z-{%egaIK(= zYY65^i4p%j+rTP99kt{b9E*Al04(n;YTJ(gFBoPd^!m|<2;y6I?qd_%q0M?xS~DUyHSpRJ$~7_S>pY^!e(|hPlPcv&~IJx#Zn+mI6o?w*$=JXiupy?z8z0?MuZ9lcWTom?@ARmCUS{CDLhH9|ryV<%B z-IvnW)D=5dETwQQSunk5Ew9adgPOV>nj}!XkNZ>!6bwCZLiVnv~A7m+i%)29%4ZW zf-tVrlmC_t@R!7QBhIOK?8ZlfueU*T9o7+F#B+n*W-1L9Y7GtAK8!Q1rEK925iMX) zFo}+Jv;3tK|0!K}JMh;I`L2oRl^FV&LL##!!4p>Qa?2K|#HELGEdOn~^u=v3WVp4X zh=XdH&@{Ye@3xLyPXFI5S0b+ysG1rH3Ns|p8sjd+N3Gx>PZ^^-K~3Cl_L8&HoFh`K1Zw26y`L(vz2CsD3=g>;C+b5=AoY-8a{@ z|3c(OP_>eKV`U4tq>5>wTr20f9}k&GLjP}Mt)0)@hva)S_NN~lSHB|>|ILC0?6)g+ z7%e3x#eYOc9QDSd8Z6#q!i6Q@<*L^2_e^jv*=A!-^;lCu8j9Mm0V_67C$#Za&!HSY`8gj{g+!8RfQtObAJ z8XZsRkQl`_W$*({aD0q*j)4$ZDun&lnnhs66gVJ6-CK;5dMYHYv7TzUxfl3jSVniz z@QUxc5KDwxD3loH|H69zYq7gECj`J%ztV=ZB5WD`Io}2aWY8}*Y8W0MXxhAnOZi`8 z^am32Klr|G+$QjbV=CVN>%%J?Iw|(r(fq>R|9jTP=XmvOv;kZ6KQ0z;HjDe)S%)2C zMp$v-8O3#)?oTnp|4>P8w+M#xs4T*%B42VP$u}jGUce}6`J4yZ%kayIYq^pon^s59 ztC}TlJIG7ygXm6P{KT{d{dNf5KX)%pyD5~tF1WJ_1V=G+9C}HZo9y!F9nwA11$8j0 z0k+}40mB2pNbNno;O0>y-Cm986dnG2HP5Y>`jHOyX*rfPM9L|q&zqsJ<45n~qi^I} zTA;w-LFxTJSjT@f{rDWKUcmt=%XeXK4@?P40n})hC@3x}iO!4@;LHz2)@O&@^%P_6 zhbCfo*+uRN!0jX~`p*QqHOGlC>imkl+Bl6WfF%e-Ql7c)gGRcVsB8|Iq|@_r+pTG= zp(9$?x)}UJp8U6I`EyxdNz*Liu(ma~^evY%HvPJZ!T4PkT;rAH4c9P@NM&(I*U|Q0 zzW7Pv zf7uh!vR4iNZ*cAj`ae0^gD|3Fo4YPq0CM|3C~ZbDtuJ;w(?62_3ll#+hxY#qz5N99 zzvM1FKa2;%pGDOC*TG+8c9glb2{nBt6KbM}so!=Xq0I9gQ}AO!@Xz`%D+<85;s3Ww zwzmP~VKadrgefzf9r^Hen1A7{d$>cc$R9}e>x~~L-l?-={QFb+a9T}wZ%3*+39^XvUj@)Z{OBMK-V7hin|h@2t+9>pE_hLeBrb&_@S2)r?+1A;0m=KYxa z?=$TePV2JNJ6yw3t}AGFR)mw1ynV3$=MD*i@>&6t&uo~PQE7N?R0m1-;Cj6c#LZpc zzU3*d!q0@0$oO6+#tKDqV?g*;hPm#(UB1u_RMP&_+7w}2)#3co{$S(`HcZM$pBM;P zO5mn4!yY*0A01NFUb-%gs1io)5t{TVyhJU<^H-=b}Z8V1Pw(#6{-ievFZFR|I>ra@-23@xJf;w^EKtT0! zSB-!^vMpa2Ktuc_<9sH?-W0+2`_Fg>{(Qj=M7tPK8RxBUwAA(77O{!5TRPrqBw}8( z{G!Md8Q4715jPtGV0G=uOBk6dXhb=P*Fa}w+)X;tBEUC0>$VUN@6z1vHO58k!3zEzx^)7w*f=DCz!5L89gpUb5L;odtMFTF$}`eWt&9dw&Ph$)1c2w}xbIZnsbJC-WE%B8$f zs0mF+G6GG}5!ulYg8> zo}#yLl(*vaZYJdo>n0`Wp?D9@7@ z4>wuTvOuaF@7wILG4Yxiv6Ea|f8O{6CVf<~ z6uINW-!^sQjQ7WK zM{JBL4athgppoHhTFRIF<}pxL6{|1!iD~TC6Y?BX5lJoVZFQ>D^m1qX$Z|}Ny}#Ps zZhK!9y?l3mGm~XBU>YhuWV<#V)@#%=uru}~oXTaQG;`aqOFsEX*pSv?7z@LtttosY zG+k1cbGxe84BR?TU=@BiGj|{8&`6L%*H0}zsF7pr{Ptez=c`fK{R7B^f$KLH-36us z|D1-~q0Gk6;%EaK4_*w%G4$2e@qQ5Xz4Knwtc?${4p~+LMr|MgWVXU;z%V@VSVRXO zSNQhhOZnb`%KhX)c-gacz1CdIBkFGIBUq33E#p!~Vy&cKqW}hz`wsp`#vsI-_RvB0 zH<}V*U~hYASo+~;8QeAn>4F4G6c>PBHZ zcO0bt>pi20%4g{^MhQq+(rBje3X15W{M*!rr_UFvS z%a#~uwu02!DwDaWx-x5fdwCPjqBwR0Q?!ij{8YscGDqifb-Jm!?(i1Ed|BxXs3~Z8 zS+ByS#e8Ij3Ef^4t#I9Q&o@re?xk)rH=yCITFc6LTp--`!T?r>%BT0ph)YrVC`siX z__E^uMYwN8Q` zRi|0pnknyj%9(EDe)|2$?0QGt_ZqTc|F!&^VDVUVkWX;)Nc2~HCv zqb0eLrm8Trw4`+yD{10zAPG5={T^_P)1!9g9ry~$1obVfd>DsL0wKLy?qj0G?zM&L zUnzmn3@D6EQqbhQARm2&S%dvFy|WL#+;s!x#z=jy`?GfCF#6{`l1%ROwcg)v)YtAg zE0fA(l1>`|>ZHiTjH` z*n57*9#YeKq>R5YWYwnB=`RM!r#`JqyFf7db2z`_@5|1+e4dU(OoM%k7j0rIAO-nz zj3LAfy8wDdxRNfzA+RzpFVDIlII?1_VY-7#PsM~ zko#ye^!~M1b6gqU6KEaDDCpGds)AW_>R}#GY-<^J>+)3UxH_d3Oi>G}n(B4#A-3MJ zKltD`_wgp&ANH)66?1@0FRp7KI3Wmj;`j99z#|__ieWfsfqGGF5;l`sk&p6udT>KY z=(agh=v9(j#-T&KuVB$L6FmYTTmk|ol#2?UMXIG~O`Swdf{orIhgZV1ULRRn8w#qn z?m$A&KR@AU9GYmH>ZGWln@M^(7xsR}*l?20o!r_PCilv>l&*~Cv%*RP=?v5t(pyvw zFqWidUkK>v3WptX&?Nyn)Q@_hFJBtM-!$iO=9J;*Xt)=FkB}dqAvY_z>jjw;ttOAblw08CEi7F*G}D3mC*9-*6OB+2s+Z$Gq+xXI8iAekjG99^xfiTZV|q=&#(xnXb?%Uc<~ z!z}=YOs-Uurt8Zyh03JD`StlbO^-RH8CsUIMg;Y9TyQeufXsC*I#;&yM?jCydZ{!d z;Hbh9z`Vj_9=UAzO+(o>X>q@0!l@*J3O#y8(l7SIPA}SUEbk?7@@N@``fXOEFA)Q2 zw8jJ~Ft&!KZdt*Q5SZMY_2PViIMGJoEas0Z@VhLB{+Ew7_xmWeCPKq*D zK@^`IllgpZqBT7g0zBHfq))(I>l03TVbDD+7kh5RBvcKc2~z%Ou=2*`8tlJ1^G6l@ zY&N%AmLz@lYF${m#DmmX???NY%g+4qrcC=-;6d;f|49}kB7%XlnV6y4(WzXfHQ2qGmC9D zqE7ervv@St7|NnHh&P%p-fUQ5N_}F5g37`;GyCY%*FP^q2y9G0ai5b29(OD^WN32>%`eY*)jue$f#M)0bVhABnku9E}wCSw0kqIy$3x z4L>^5?NGaWT|{n)VK8UXSK~9ScAnCbBGyvXnKfej~o0YUrn_=-J&(k4KlE%{yqa>sU#q77^fyv z$vj|5pMjcbd4`s!?_?l0Xy7=|tv{oeEveH-pYK1fHXbnke>rfIhTEE4JeB@3e( z5xU{2rza+>!|hR~TWf2@>spiR4u^j`Kj%It z#Np2X6J!grLZAK7@+zO{Y!UjSWpoj$--l|YdoZV(*3RiNwn4u`X8fb!)qL-s{uO1Qr~-g6V??< zrGkMz@m36L1Zqc`K;}?VGA!gm(B9R84-ZG`=m{{mDvz&c3DMHJfaMV0A8tV#u zc>{gmK`39%gsO3!UBS4`eFbPx-BB4~NLZ}n#|n2S#q7wiLqXv#e7;LSsRqtSlr(r> zuV)m*|2|jS4xKp1CiymS8LPbBspr%-COwVI%`(-B+-m8m;pzU;) z>fpGu@yAB@vzi-xA$ILAZ-eD3XWK(uMb{Z^({q6uF!<1{m)D?z`LD=TM<3-xS8`|e ztK0HebPK#M9jM!2lLUJF^n)2oZyx}?#v|9pr)BrAT7b2nP?ShAh!vkraNLWNv5cs2 zp6pWHj+Zfdpig`aW`CJAJHJ!TD5Lfl_LZsw6nJNS?b>PiY1~h(vAuy3jzl0&OF#wF z76C(Za_hl)#5#bsL{KKjK59s1iINfcXnv-8Q3nqi2^4+rt31j|I68F%c_#5v8Ywpa zDrKBEDs44NRApm^DyszZL0y~o?+UZjr6~gx`T*K+JTOcQK)@G#PJNXdJ?YK{gMQNQDAWWQ^m70S?9BMG+3uvJz)ZstJLxIDz ztnoJ`N6-0~$u~;(P&MYmyAZ`;a*IJp$P^4K>9pm`l>{Kef~n|cKBy&d2T>(7^$!%R zWUT&iNpuz=@0T8A#d>!A^K6_U>es;o5yr&oI{Q%sN)CPKet9Ma9{?BC3gD*(dr=!| zo3o&?-kjQ zm&2#9!ffO>V9k_wtx8h^v@ZkT@&TGA+e@WvhFwVgf>OhLhBCfCVSy9=HCyJy=TO0b zmEg*&lgkZ7vE?s1fS*fsF|ToYPpg;?|DS-V5NOL63{jZL``w{g&^1@8_>dOdI^004vgA7;mOG!fB%&Vt8f*G~a-&Rw#0tYH% zKvn%1)u35GgGQy)Nf>M5LwN1kZs5d}$c6jnp498J8$R=e;%K*^QF^luGuWM&2AXcx zTty`v=I`xsYL5N$-rNe@p8HQ>eN9KkP!jMs{r>t6;8sOo&U3485C3_zvL%LhgLxAJbb7kQ(3J!RE0&a zP)Pl+S^L*LAo%md8Y6RvRiCd`kHoB)PtR918}m5OSMR#p4I-yK-lF`sP6w8ofd99S zxIdn_StZe@5{RSW7uGh{f$;jBoqwixz6h+pdzA5p+>$5ll)yApGiQI;dc08|cB3yL zU+WkBsH4A5p7G(0^p`7Vxr|3J@;|?y;@h*m*~ho6#moJTnH(M&+|*ti?&Mb=6zdG_ zdWXW54}|~W zA<(`Pq@R+hWhti8K~vhVxb$z$HMi6<->nZKwdkbd7y9clYE*s2;mETz^fc?N%3)F_ zVuQ(BxML=Ie0(3aB@N^^u^*7@3>19>k9V%b!*rs%>7ul>Uh^(B?F&vA4c!L~`4H7n7 zbJER0W!WQ$)SObhSs&E;#)gxa*|6xvy0;rp*DKo>M|;F)#~<|Tx(~nQq5cZvDCi_{ zms`&A>NQ}U@(!+V`n+xLyxhPM+?BNY2Hb)_A=j-Z&s$rh4Q(IrKb>``m!+Sv^@#5u5O?*$F06N%&0x1${YJ3uS$9f!tn20P3P{79 zZ2QeKyaL)7TV(F>cUp8sR7@%iE99Z7vw4AL6a2WFcI;yCOHFeI$28k4#AHVBh>&02?y$OCge z>^#fgTRhHp5oP<#yJpLNK(DLv<=tM8qj^#_YGT91a<9^{K~pBVE(`6kiQ{ZuejfJ& zlXr)~QpHzqxMfAnsfIHxZTpIGKD9_%FNg_S|Mi!3Af(iGrQ(ULY7rY}9thpeoqSC! zgjtqE6H7ET@jyUZsZ|O;i6y3CY##h-Eaf_l`uA>fY`Tcx{-}?G zX-aDNRQJeBS2u|FoLQ(Oag>%WbtBe^!tCP4?WuWYyye^ zb|YeCj6wc3{v{Qsx5ROk72}*7dGR=o2w_slD3NK1S{T-c+`-F0WcE_0^9J>3Cs;d$ z49mC)S-3OX2KAQ){wLh=_*-_0p@)~%+^V`Hodc1$pXCM_;{AHh;*sJOTRo+xNU5LD zQQR>tm(uI2e$Z_|Xg`o*IhvgtDkd!cDkOo$!niPDXq?*s3{!mKlVjS4j?E4GgSi=_ zJcH7@Z`xBNb`HkS>-984q7Pf$ce`BQmN+Bs+ zSG)fir23W9&*$P!Syuvw(M!fbTb!z;rA6`qYv7s)v%@f4*5Y0`=}V5gGx1n{W8_dX zPd4!^Ua`sx>#^210?)3aM{No%Z7}hZ;aTX?x8?L}5hlr;!P7Y<4&(B&6SMP-w;vfY zMhfKS!?nK9FVH1d%9WA8<{$~`a4xSC1l~d|>{&U|rLwSOAtwx)(k5fuBJUJP4w|ZY z)vz)tA5lzWq2Gp}ZblSd5@;OKogDzhWxWO@>zSHyWZ(C7Op|>Nk*%={*_Rp1 zjCpT*p5Ocbzwd93bLN~mm;2hj`{#3Ax3Pk~i}-WLnWV|4^=P;oJ>P$fd1G%bhj#o& zot8=CmWE8iOPzYzrU+rzjA^AYBi*vg&@Yef$=!rFblzZHo#$X*t1jXdYVSf7T_@(X z+02?$PYZpt+z>*clNoflZOYEAunJUq!RfT@Fq8HZDxYJ)6j40mxI5Igii?(Y?!ooH zno+>_?DF!xYt<;!Cb#{&eN-!LQ&)%h&wkIKAmZ|JXNhQT_*ky~>hkhc(@2BN`oQ6c z!1N?BCBn{w(p!_&GuCD`cXFSF9#U=(3|?Cfj6v-$v2RxRjK{4FSJk%4cy3AisIEp% zAnOiKf2WbsAnzF|NQ-V={9I}-;i(Y^m6v3b?9-CmE3aYL&8kER42UIHVw{Lq!}s7u zWb|5}!kO0=9B$GFKElR)6TfNt{^XhY?T4@QSC{%eO1_pW{-i+G|65Ogo##7G$Vf5} zn69Thl|%ooZ#(Z*Q%+WITzS49=|Oxo6|krHp=)q3)~&5FoO5F#ExSACGX<4ojo?yV z1*f=9g@4tTxm6p6rVWRv6a4^kLR$J0pBm50?N7#tBi|1t9_S{1?0q#Zz~QGtNDH_n zQTjO$N7K#{b>4yRd!zno_gZ7;vCxXDP#Vy+J6X3}&2|u!K%q*qx6qh!&7nTUy zquXct8e_GMV?ZlS$Myv_XW}Tr9LI^wTGcf~H8Pq7smGKLa(?#*bw56ti27AzY3qiQ z+}~oTuu-G=!z z3f*`}rTaTR57z4;OkOrN<$UHNUvZRl-jvVEn=1U!;nu;H5>aK6QjV!qs!GE*%N5{1 zL!rz{wZR&wlv-dM#$srDUY`1pPW;?p}qMt{6;bP zAN#-Rr9xIHc_RK^`hJufrcFYWKPGV}_6HFjm&!|$=l$J;~1ApOx z{Kq|Xje=(GCoBIAUi6G6;i^I=+hs_VH>~xMzCMI{Lk_EG9JF0~QNl_l7?Tk91W2;K z(IxgaJEjo!6f>pvef-Q5T#du3O3j%Rhw>Qt+s}971#HL$!o?nn+3O!Z4Ur#m9m(mK)ia~NCUYD-(D zpH1CvHb&b1+@BRAjxOEFZJ*Oeg9c7cPGYOC@a|%}2UD0t3uwP>ds-KGtmbN2Fou|T zvKrwV7$!RmAw}Diy51j}f7pFY8gF@Oxc^Mv%x5K;oL7r>`bZ-F_1hn$xAVr-Bd?yT zQmYEJucgSfUwbsw1apLFXhf((7L=9oIu$ZKDob^IiWEJ#)#Yo}NbMIb4I=C^oL&Ji zFZw|?%y-TnNVrKxsUJ<>K%BpQII z1*N~%EOovpOUv;F%A)J24j|g>Yy-G|(@_q4I%hM}1)p`Y8 z=?iXE&lxpVI}!>CMN@qDWmq(=!lP-UM>)mE+l#>w)s(@4y9bYA44UoorqnsFjUk0L$uCWy*o8@YLBf?YWUkoz8oSzFuC##0&3k zXDjnd&w(|=uR4E`pm-qV!EgGGegih0P$`_&dl=#TgzM6kqer8hhu>DcC&|sed>VW( zGo5bH_w(tbbEn=Ss!483;W5HAHPi12nreKd@fFVGk$?*yUvQ7rl57cAbybu!Y(+0K zh}!tm$?XWYRPl_hiXy88Ls9ND@LqQIH`!$|( zhUYGEqKEoSh=YQ zAM0R_Emcg@`4zQWp4j0@3$F-lu2lm9Lo6Bo!;U<87Bu1f1T2dUnZQP`3@vIqMiD&h zkw33|^SIp8H;|&!qLhgEm_8(jC})2j&0x>AGJ^@xe=_tGNK5>Qc4qgQMJn4QOGZ;D zw2Ba+$iR_C56KRNe#Km!Dz3~#ox8Vh+TP&JF>B;Bmq)3-xT4k2<*bypTU}~Ps{^BY z_B>M+yI-+Mabm@nGksDObV;`O7qc0Z-X3R!Fa@9Zbfhk?7*FUs`E=+)0x-zR*eQlP z-D5)8hR;_B;9#MwD7`Q~%3~R>T8sz7TjV7}CPUv1yn{;=0^_nBJ=}M0h8hAWoeVM1E#hJBbvLiAm1WyNZ*kPZXoP_qy0Y@AR3b*mxCMSi2dw^5 z@ew!~vUQb7>OHnx;dc_WVI7e*ti)P$I3pbRuF9dm+zXtu6!Y%fHRP_!OIBsz~bFkbD=+nk-8myYS!pXa884)^S?~f<`fmU zv-*ts7a0iUcZ0=s26T2jJg-3X60i^P_#Vycrp*~6OftH9+MQ-yYiOTbHb&&v?O;4y z$-%k`JbrV+dO^@J-^Y=~6J5Z|yJp=Bn3(r-)=ZZ0luhfn?;muz-s!sO<6qd@=*09t z2?~Pdmt`nCUd&enkAfwh-IThVbbEFXURO(|mqM99_D3YykNG~y-Yj0!v^6eG%O}!+ z)H~O6v6B@w$UNUVGUrK?n$T&;w2g01t4O*%Cjpk_Rj_>%d*J1T^8N@2?9pP+cSEejdD(TlSM67v3Z)aGVn^+TIDwTf%I?0N4; zT|V`5?j=(w!t<;%NQ4WmCE5>fdS`hxxP-Tsd(K|GqQaEJGm!-O5o9Eq^*PhvD~A!s zE~EK%8Kj5?+OV`@mHH@ERs6};MRQgSQZpOB0bjk5du}}$cl(WhRVe)GgyvaTrTwvo z9|-q!fqmVwWVMP(w2i;=-eKKMuP@AqZGbuQJ5dIcsopk?bdm8lh3;JB3!53sFLJno zM{d(^YL?;p#_vv(*!tW&Y8T!bG>G4E><&|y=$&ZN)3j=6x?d`*Ky9mb?DT3+=hkV>PZ|g_9SRu^Xbd+PXQk@yczw?- z(xHKle;VPv#Y=`6ABiY16f7-Tc%-Lke=$n_hD@^5wO)>oAAT-hAYl{qSpHR_FW!O; z>KxBHM*&%K(_1lV|) zVB_8GCt9UZ@>j#M3S1*N1gfwjyMYoD&etXBy!qFxOzZ=xvZg0PPlw9y!~B>brC4)D zT(A5SRsO>W4S2mRJamGDy*Vu7C9_;OBAuDPIuw8kdIam0w8gad;+un4WEDu+M*n3eT$ zqOp62ec8Z?RkVAkB`l9^c>P&_|NS-O=o?LrA1eayO7mw+)ROLKI|shz_g{}{<71v? z@Nn~ae~Quo0i@PI;9hRpOme~4EAf*%t5*ai*Q&`@=<=mV0tCHN!ThoE1|;WdU;NHi z4ps4I$i48^xDDmLr>rat>A(JMA=vf7g2Xej!h~JTq9+fHAD|N*Vs3qCS;k>`0Gi2J z7PM0Tz_)ulT4QTvyo0+|XL>&Ffoa>0q(xjy<|M|>*0#j80j$Vqq#~}LkX_)T%*V!A zUMs!+Y-oPAmaMTPT+Y&fFPB%ok;CYMXHIRaPW-`zA(_M1N7_I7J6fMs@`UJWzjt@T zoq|qFw8DcJ3?@O;#Qy;a`NbX?i6e5;sJZ0l&H1mXD~|(j#rH4obdPT`Xmqp8_7S>F%`^tjJ-Ev$KSVWa-_Xm zC5lD<4puOeb&fCRZoaxOHR%e#wx3nVo=!-xT&ceHNZ|avH*_z9_cQ7Q-EH#T4!-is z_FPir36Yhbk#>@xD3p{sULo(#Hu<+m9cOf(eL-v&Bld4?;rYX0Njq6AZ4T?dHD}%e zyxFVzcmWFKzdCY71vq-4ICYj004DF2+a+NSszffBmSk9m|J=SekauA3(a0n3F^tw= z&noYf1tDu;)A7CyKJID{mtn9H!W_GhLJDwa;(ygbFN+C z)+^x;QM&MJ@NUc3UUWdoc3GHoH~*u{btJ(mmt)63X?>OvK^im>#IQG0xnsbua-QgU zaO~Qf160{m*0K$DVip%>CdC!PriKognW@aX(vux$U3k3*+2!RW9Lu}?&RsR_4X^VwNFa?Tk3l{Y0p9ap%4TZF*Grkzp!ua zi8XPcv^`xnJ<7uM*B|ObihJAtE$aUVjbU3`U%#NI>HhrP7zRKEb4rtvAu7MEgKAl> z%{t9HCH}=x06ea_0Jw3$QcUBr?R%(68ZzKdOP6$F3&3=P9FIgk4xl*fR0k!+|JwJ==k;i}@xKpQ? z2$5pjmh(8?8e{LYodh1x%RVOl@o~VL6ba=z@j8JjWZQTnKtb}|XbmNggjHiSMf7bg@U72aA29^*1s8F3US1`s;(d{KW|Qb#YNg zU~Hb`*d9u{LnKVT3bH;np5E~wPya+t?UWv(k0%6^ch z=kw~?^;mlTL)a2dw}<1+|7tCp_(SKf_A)b~B7XR8=sY{wf&kf^JCNTqK3}ZefB3Hq z07E^@fAVK;tlrhtRkjNH`34(ZqPNpg;86A$EYPT)8Zc{#jXrYkN-;G`FFe2O11QNO zzw-z^a-+U88Y?-#w(3(iI@2-q)SuihG1;EOw+?S(MNM=?pVFDqN?Z3mYuytglx}_( zke0Ei@V<0qdDG*6^nb0OyBgYMo1z{m9rb?ndsdBPr-FQiJGOC+u^@*<)*?+W z)1H8dNex3L(tk*nz((5@=qH{ptc4a|tqhesCZCX6W-S7WoPFH87w2|*Xw`JK$DdyR zmvW?+pa!T7H4s$TNf@*6N-vuy_KvHCnWj890e0aj)mqYp1}fQkfC<;aZIxH_wTP?E zX9FL|luGI(97X;j-O4M9WxrD&bSjcUn`=hur@G-=1ocC4sUQ1fmtcuc~4Q4C+j)0Mi3Ftc&O;Z-G+x zzqFb&B{-$2f-qM>UwLo6WdVWyX{7}_llO=*BWm)0_$n~~qx`Shfk1TsTR;Eu&ilOnGa!V@ zDJX3RUi^P`QH5elodiT@+QkXFNCpn2xKz~MS#|T&H6&XL0+(n0!<6~k3rwjdYS16E3}MIt+l3- z@a*6WN2-Bsr|MP22V{n9xqE6Jm?RVX{YQ|jIS_E0JmJv&$KUr?=lKCuJrv(B@ zNSl|0E{1t8yI)d@j+f5m(WyDN@>qq1W>Ix2jSo*IV-J5>Ie1?J{q%)@j&_OpWKU}o zby^lax)mi|R|EomC)<#^aNma0abnPUELYA{rSi+rj37N!OgH`I7*2k0<;$wL0osTv z$1*I63ItMgTC(2H8gngpUf&xGIdYXObO7GtOpF%%EP0p|d*{wo>pnRy|$454kfT(k5U zB7Y;~M2w)gq{zbJI{#BXkjY<}29nDQvexc&FSFU*sp#Gv*8O#y!oAPZiW69x=vzS0 zD84IrI*2ACl!UDFb-X%+R4jSzlYm}YFN@vvFKU3q&lsp&>_I5qQfAdka-e7C>bX3k zQT8$eiqzhaLN}fR6*1YqLuXnc-hj1(W7^Enh4QUg#P^qf_?tN*q%EB>GCtzTEhF(i zsMvFWIVAJ-aTFyp4&T8_o2oE|DAly50My6FT`i$4TcPYfgY8^f^P05mO)_xR76Wp? zUY@6Ty*aUu3vdl3GC+C%w%P4)wLz_|+Jup$}4Kn1W4)z)DF6(5JEv0=djspE@#- zj6<)_rPH6Rf7KCNq@gFBo~w!xC#~zmqog;3!{;;TM)z6h)`KL^74e3Jg;7!lAH8)Q zP)LkF4`@vF;tBmgz@cN1M!tCdbbwIoUW5wS3rJ?@3&LwiN7hcQp#zly$tK{jLFgo< zoiu%@KI)MEM+aCf7oUWfsvr_tg~5XcCa~6MG_?W*n54UnxwY@bbYMVwJuvJoOoGGa zD@>+8k7$V6t5ke)BFc(;V{M4IsvCdH?_ff`iH@H1olB9$_vr_FOy879L7*~lr$<@x z7(97C{;;uXKsERLhPiI?qgbTkay&5Mdm+HRM)ymvC@NC+YzK1?udQ$yae?WR#V&c? z!lTi_hzyL=?Z6r7vHg;&v(F5}}C)tdQU<;IO(;F4wEb1oNWECIC zz+_3OT)zc4-p|2LtHD}B=z_IQi+K3gD>DovAY}`i5+jqO2XpE8Mw1`nCy*u8Z`UYF zXe&6b2ProMv%=pQRRD_-tg7E6qH%4% zeE{DVhB{ozDn((pYB5CveNf{cKq;!NByOzGf{6nx=31DfK7B6k<~i7swL3E}Fr1Ic zA4j^5V*@NOzQ4KMh$p2Y`-QeND?Mz+1ucT>;Zq0fLB!+Dpw;zg+?}1Hr@8^NZ6x@Y z`JTY0zbN}Yjl*IAsnZZp-(T{;u8rTvO_72qc>FfkU(Fxw(TI~Lg>FO!ZvFzO2|0S@ zRenbOKA-U48KJ)0`NXXl490gL34F*t4WA3ut{}f+2w3CZH=&`V4+FhFGYZlrqI%K% zr6}(|wgZ9tzfZ8oPy&9u6p!J?==&Bsq`p9SsB-&iQVmiGt*GNqic?Mq%$*(f(s;66g*KHc(vcf(Bfv`aRfd1XheLJ+EV(o1JGzRx;^{C{YPXyazquAnU2yE_Us?@+=t~p zQ^bv0M5|uLoxknkLmAtdhu+GCPF;n1 zcMK44qB!D0jM7oV?Yo_3cYh5anBNE7_uOdoQbq39H~U|Zp=HU{}_v*5{~$CW|*fH>eI-0%annB%egbCkCpy+c{v?o((Q z&dKqQCxiMJq!m$8K}kSg{cY5tea@`LnCsud00bM@PAux=8x%H2BaS&5^K=W?{S!k> z3VMo#&$qx%JK%!t?-Gwgm3B+q;Dj}z?+7??Soh~Ol5ODq0`V+bqf@hm`H!^SxCIZM zsUTmkgptShE&T?}?%ialvXh6M`0!RM%Om`daL_zP7k}6%-sB7HEb7=1+YetHQS$GA zOcREc4o6|!u(go^(d_2kg)s0|y{@A@JNrjjJ36w~p4>@&C=wf^`FZ{>O8v@dwu0wM zZTa()o^NxE*Skw#677Fr;Rc`aM4W^oh>P4!xbij>agE>^6GSBFA_@Ir1Mo#0d@q_E z2R{;j@|&k#HGbNbb+T>GVHuLfV=SQymnnog+6V6Mgk>kql9h+3ZDpBlm4HBhTCQRe z@+MsxC=z?lj+btDBOeac3v_vxebA4A??)+Zm%>-D8cNOhKjKY*SYrs)7W9F?i2*>z zfrNp;HLGd-5hWP6GDR+N-ZAfMqkb$HJ*6enLjS5X|IzQT%WH$|FGGU2+-pFfO2^KJ z#W}6KQ4hYYwvJ)Ime=WOYITKk|BNM+dEVEbv%Z!M-}_Sw-+>Z`Y7qxBwFvx-#b)5z zx(0l0)~)$47fgJL4psqcZRWZbb^2P#j?+nxHdpw=Z1FW$N~yS*fa6o>z?c>^7CXED z=jeFBpW?!6y2PcyQh51{>kTt7wdaex$E3EIs;ADP21L^=2=VgGFN&d;452r}>51Wh}m!DTqB4Kabzoh-#VxmO==R1d$ zZk^}uUzw?$6fBQQ2}KkY4R$d5U+o0k(pS~{O#$xZw}7dRVMd>gUS<;u$>!wA?HQ=M zUK93VB-k{C6ve~DB2GOCp?>E_zY$q)(?{S+mlhHMd`)?Q-fw}8vxfT~%$F$w76g$-n1`6hDm%L7$p{QA+0YD)!J z?yVnz%aW$28U~vES#5=ammvd}*GG1#a~EyVXAb-8=hk+F6N|_ltdBk>VUEs2$&?m_ zS$bQ3Oqrl>Qer6&bP?|FKygG#auy8GY#`~HBu!HxZY%zJ?JCwftw7~&>#oCj_$&wn luEW)QtH%x5mW>7z>Hio)&U4B?k2>xBzM76|$zAJ^{{zcG;}HM= literal 0 HcmV?d00001 diff --git a/resources/bitstreamdiagram.png b/resources/bitstreamdiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..33c96bfef76a30b27cf80bfa0f75af23fe3d98a1 GIT binary patch literal 222164 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

    -G{0(~UPbq}Cu;Fcc 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 N69Y5-GCljK{{vH))1&|Z literal 0 HcmV?d00001 diff --git a/tools/60-rtlsdr.rules b/tools/60-rtlsdr.rules new file mode 100644 index 0000000..e1225e4 --- /dev/null +++ b/tools/60-rtlsdr.rules @@ -0,0 +1,2 @@ +# Realtek Semiconductor Corp. RTL2838 DVB-T +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", MODE:="0666", GROUP="adm", SYMLINK+="rtl_sdr" diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..ff6054d --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,17 @@ +all : complex_magsink_to_image image_color.png image.png + +magsink_to_image : magsink_to_image.c + gcc -o $@ $^ -O3 + +complex_magsink_to_image : complex_magsink_to_image.c + gcc -o $@ $^ -O3 -lm + +image_color.png : complex_magsink_to_image /tmp/samplelog_I.dat /tmp/samplelog_Q.dat + ./complex_magsink_to_image + +image.png : magsink_to_image /tmp/samplelog.dat + ./magsink_to_image + +clean : + rm -rf magsink_to_image complex_magsink_to_image + diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..2ccaf98 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,14 @@ +# LoRasoft tools + +testloradec.grc uses https://github.com/tapparelj/gr-lora_sdr + +and is currently configured for an airspy. + +But you can configure it for whatever. + +If you do a run, it also records a file to /tmp/samplelog.dat + +Which if you only record for about 1 second, you can convert into an image with `magsink_to_image.c` which outputs `image.png` so you can examine the stream. + +If you want to compromise the signal, making it wider to get better granularity at the cost of temporal resolution, you can change FFTSIZE (in grc) to a different power of two. Then you can update the `int width = 512;` in `magsink_to_image.c` to convert it to the right width for examination. + diff --git a/tools/complex_magsink_to_image.c b/tools/complex_magsink_to_image.c new file mode 100644 index 0000000..78e0a99 --- /dev/null +++ b/tools/complex_magsink_to_image.c @@ -0,0 +1,196 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 + +#define STB_IMAGE_WRITE_IMPLEMENTATION + +#include "stb_image_write.h" + +uint32_t HSVtoHEX( float hue, float sat, float value ); + +int main() +{ + FILE * f = fopen( "/tmp/samplelog_I.dat", "rb" ); + if( !f ) { fprintf( stderr, "Error: can't open /tmp/samplelog_I.dat\n" ); exit( -59 ); } + fseek( f, 0, SEEK_END ); + int len = ftell( f ); + fseek( f, 0, SEEK_SET ); + len/=sizeof(float); + float * data_I = malloc( len * sizeof( float ) ); + int i; + for( i = 0; i < len; i++ ) + { + float val; + int r = fread( &val, 1, sizeof(float), f ); + data_I[i] = val; + } + + f = fopen( "/tmp/samplelog_Q.dat", "rb" ); + if( !f ) { fprintf( stderr, "Error: can't open /tmp/samplelog_Q.dat\n" ); exit( -59 ); } + fseek( f, 0, SEEK_END ); + len = ftell( f ); + fseek( f, 0, SEEK_SET ); + len/=sizeof(float); + float * data_Q = malloc( len * sizeof( float ) ); + float * data_M = malloc( len * sizeof( float ) ); + for( i = 0; i < len; i++ ) + { + float val; + int r = fread( &val, 1, sizeof(float), f ); + data_Q[i] = val; + } + + + int width = 1024; + int height = len / width; + + uint32_t * outimage = malloc( sizeof( uint32_t ) * width * height ); + int y, x; + float hueofs = 0.0; + for( y = 0; y < height; y++ ) + { + float linemin = 1e20; + float linemax = -1e20; + + for( x = 0; x < width; x++ ) + { + float I = data_I[x+y*width]; + float Q = data_Q[x+y*width]; + //I= sqrtf(I*I); + //Q= sqrtf(Q*Q); + data_I[x+y*width] = I; + data_Q[x+y*width] = Q; + data_M[x+y*width] = + //log( sqrtf( I*I + Q*Q ) ); + sqrtf( I*I + Q*Q ); + } + + int highestindex = 0; + + for( x = 0; x < width; x++ ) + { + float M = data_M[x+y*width]; + if( M < linemin ) linemin = M; + if( M > linemax ) { linemax = M; highestindex = x; } + } + + for( x = 0; x < width; x++ ) + { + float I = data_I[x+y*width]; + float Q = data_Q[x+y*width]; + float M = data_M[x+y*width]; + float Mm = ( M - linemin ) / (linemax - linemin); + float hue = (((atan2( I, Q ) / 3.1415926)+1)/2.0); + // hue = phase (0 to 1) + //hue += y * 0.16666666666; + // Wat? Why 18? I literally can't figure it out. + hue *= 18; // It can be 9 if we add an offset of 0.5 per pixel, but then things get out of sync. +// /hue *= 3; + hueofs += 0.466*2.0/1024.0; // .46666 "would" be perfect but striation helps us see the signal. + hue += hueofs; + if( hueofs >= 1.0 ) hueofs -= 1.0; + outimage[x+y*width] = HSVtoHEX( hue, 1.0, Mm ) | 0xff000000; + // if( x == highestindex && M > 1.0 ) printf( "%f %f %08x\n", M, hue, outimage[x+y*width] ); + + } + } + stbi_write_png( "image_color.png", width, height, 4, outimage, width*4 ); +} + + +uint32_t HSVtoHEX( float hue, float sat, float value ) +{ + + float pr = 0.0; + float pg = 0.0; + float pb = 0.0; + + short ora = 0.0; + short og = 0.0; + short ob = 0.0; + + float ro = fmod( hue * 6.0, 6.0 ); + + float avg = 0.0; + + ro = fmod( ro + 6.0 + 1.0, 6.0 ); //Hue was 60* off... + + if( ro < 1.0 ) //yellow->red + { + pr = 1.0; + pg = 1.0 - ro; + } else if( ro < 2.0 ) + { + pr = 1.0; + pb = ro - 1.0; + } else if( ro < 3.0 ) + { + pr = 3.0 - ro; + pb = 1.0; + } else if( ro < 4.0 ) + { + pb = 1.0; + pg = ro - 3.0; + } else if( ro < 5.0 ) + { + pb = 5.0 - ro; + pg = 1.0; + } else + { + pg = 1.0; + pr = ro - 5.0; + } + + //Actually, above math is backwards, oops! + pr *= value; + pg *= value; + pb *= value; + + avg += pr; + avg += pg; + avg += pb; + + pr = pr * sat + avg * (1.0-sat); + pg = pg * sat + avg * (1.0-sat); + pb = pb * sat + avg * (1.0-sat); + + ora = pr * 255; + og = pb * 255; + ob = pg * 255; + + if( ora < 0 ) ora = 0; + if( ora > 255 ) ora = 255; + if( og < 0 ) og = 0; + if( og > 255 ) og = 255; + if( ob < 0 ) ob = 0; + if( ob > 255 ) ob = 255; + + // Pack bits in RGBA format + return (ora << 0) | (og << 8) | (ob << 16); +} + diff --git a/tools/magsink_to_image.c b/tools/magsink_to_image.c new file mode 100644 index 0000000..f7fd892 --- /dev/null +++ b/tools/magsink_to_image.c @@ -0,0 +1,82 @@ +/* +MIT License + +Copyright (c) 2024 Charles Lohr "CNLohr" + +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 + +#define STB_IMAGE_WRITE_IMPLEMENTATION + +#include "stb_image_write.h" + +int main() +{ + FILE * f = fopen( "/tmp/samplelog.dat", "rb" ); + if( !f ) { fprintf( stderr, "Error: can't open /tmp/samplelog.dat\n" ); exit( -59 ); } + fseek( f, 0, SEEK_END ); + int len = ftell( f ); + fseek( f, 0, SEEK_SET ); + len/=sizeof(float); + float * data = malloc( len * sizeof( float ) ); + float fMin = 1e20; + float fMax = -1e20; + int i; + for( i = 0; i < len; i++ ) + { + float val; + int r = fread( &val, 1, sizeof(float), f ); + if( val > fMax ) fMax = val; + if( val < fMin ) fMin = val; + data[i] = val; + } + + int width = 1024; + int height = len / width; + + uint32_t * outimage = malloc( sizeof( uint32_t ) * width * height ); + int y, x; + for( y = 0; y < height; y++ ) + { + float linemin = 1e20; + float linemax = -1e20; + for( x = 0; x < width; x++ ) + { + float v = data[x+y*width]; + if( v < linemin ) linemin = v; + if( v > linemax ) linemax = v; + data[x+y*width] = v; + } + + for( x = 0; x < width; x++ ) + { + float v = data[x+y*width]; + int intensity = (v - linemin) / (linemax - linemin) * 255.5 * 2 - 256; + if( intensity < 0 ) intensity = 0; + if( intensity > 255 ) intensity = 255; + outimage[x+y*width] = (intensity) | (intensity<<8) | (intensity<<16) | 0xff000000; + } + } + stbi_write_png( "image.png", width, height, 4, outimage, width*4 ); +} + diff --git a/tools/stb_image_write.h b/tools/stb_image_write.h new file mode 100644 index 0000000..7365163 --- /dev/null +++ b/tools/stb_image_write.h @@ -0,0 +1,1725 @@ +/* stb_image_write - v1.16 - public domain - http://nothings.org/stb + writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 + no warranty implied; use at your own risk + + Before #including, + + #define STB_IMAGE_WRITE_IMPLEMENTATION + + in the file that you want to have the implementation. + + Will probably not work correctly with strict-aliasing optimizations. + +ABOUT: + + This header file is a library for writing images to C stdio or a callback. + + The PNG output is not optimal; it is 20-50% larger than the file + written by a decent optimizing implementation; though providing a custom + zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. + This library is designed for source code compactness and simplicity, + not optimal image file size or run-time performance. + +BUILDING: + + You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. + You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace + malloc,realloc,free. + You can #define STBIW_MEMMOVE() to replace memmove() + You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function + for PNG compression (instead of the builtin one), it must have the following signature: + unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); + The returned data will be freed with STBIW_FREE() (free() by default), + so it must be heap allocated with STBIW_MALLOC() (malloc() by default), + +UNICODE: + + If compiling for Windows and you wish to use Unicode filenames, compile + with + #define STBIW_WINDOWS_UTF8 + and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert + Windows wchar_t filenames to utf8. + +USAGE: + + There are five functions, one for each image file format: + + int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); + int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); + + void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically + + There are also five equivalent functions that use an arbitrary write function. You are + expected to open/close your file-equivalent before and after calling these: + + int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + + where the callback is: + void stbi_write_func(void *context, void *data, int size); + + You can configure it with these global variables: + int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE + int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression + int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode + + + You can define STBI_WRITE_NO_STDIO to disable the file variant of these + functions, so the library will not use stdio.h at all. However, this will + also disable HDR writing, because it requires stdio for formatted output. + + Each function returns 0 on failure and non-0 on success. + + The functions create an image file defined by the parameters. The image + is a rectangle of pixels stored from left-to-right, top-to-bottom. + Each pixel contains 'comp' channels of data stored interleaved with 8-bits + per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is + monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. + The *data pointer points to the first byte of the top-left-most pixel. + For PNG, "stride_in_bytes" is the distance in bytes from the first byte of + a row of pixels to the first byte of the next row of pixels. + + PNG creates output files with the same number of components as the input. + The BMP format expands Y to RGB in the file format and does not + output alpha. + + PNG supports writing rectangles of data even when the bytes storing rows of + data are not consecutive in memory (e.g. sub-rectangles of a larger image), + by supplying the stride between the beginning of adjacent rows. The other + formats do not. (Thus you cannot write a native-format BMP through the BMP + writer, both because it is in BGR order and because it may have padding + at the end of the line.) + + PNG allows you to set the deflate compression level by setting the global + variable 'stbi_write_png_compression_level' (it defaults to 8). + + HDR expects linear float data. Since the format is always 32-bit rgb(e) + data, alpha (if provided) is discarded, and for monochrome data it is + replicated across all three channels. + + TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed + data, set the global variable 'stbi_write_tga_with_rle' to 0. + + JPEG does ignore alpha channels in input data; quality is between 1 and 100. + Higher quality looks better but results in a bigger image. + JPEG baseline (no JPEG progressive). + +CREDITS: + + + Sean Barrett - PNG/BMP/TGA + Baldur Karlsson - HDR + Jean-Sebastien Guay - TGA monochrome + Tim Kelsey - misc enhancements + Alan Hickman - TGA RLE + Emmanuel Julien - initial file IO callback implementation + Jon Olick - original jo_jpeg.cpp code + Daniel Gibson - integrate JPEG, allow external zlib + Aarni Koskela - allow choosing PNG filter + + bugfixes: + github:Chribba + Guillaume Chereau + github:jry2 + github:romigrou + Sergio Gonzalez + Jonas Karlsson + Filip Wasil + Thatcher Ulrich + github:poppolopoppo + Patrick Boettcher + github:xeekworx + Cap Petschulat + Simon Rodriguez + Ivan Tikhonov + github:ignotion + Adam Schackart + Andrew Kensler + +LICENSE + + See end of file for license information. + +*/ + +#ifndef INCLUDE_STB_IMAGE_WRITE_H +#define INCLUDE_STB_IMAGE_WRITE_H + +#include + +// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline' +#ifndef STBIWDEF +#ifdef STB_IMAGE_WRITE_STATIC +#define STBIWDEF static +#else +#ifdef __cplusplus +#define STBIWDEF extern "C" +#else +#define STBIWDEF extern +#endif +#endif +#endif + +#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations +STBIWDEF int stbi_write_tga_with_rle; +STBIWDEF int stbi_write_png_compression_level; +STBIWDEF int stbi_write_force_png_filter; +#endif + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); + +#ifdef STBIW_WINDOWS_UTF8 +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif +#endif + +typedef void stbi_write_func(void *context, void *data, int size); + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + +STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); + +#endif//INCLUDE_STB_IMAGE_WRITE_H + +#ifdef STB_IMAGE_WRITE_IMPLEMENTATION + +#ifdef _WIN32 + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif +#endif + +#ifndef STBI_WRITE_NO_STDIO +#include +#endif // STBI_WRITE_NO_STDIO + +#include +#include +#include +#include + +#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) +// ok +#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." +#endif + +#ifndef STBIW_MALLOC +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) +#endif + +#ifndef STBIW_REALLOC_SIZED +#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) +#endif + + +#ifndef STBIW_MEMMOVE +#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) +#endif + + +#ifndef STBIW_ASSERT +#include +#define STBIW_ASSERT(x) assert(x) +#endif + +#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) + +#ifdef STB_IMAGE_WRITE_STATIC +static int stbi_write_png_compression_level = 8; +static int stbi_write_tga_with_rle = 1; +static int stbi_write_force_png_filter = -1; +#else +int stbi_write_png_compression_level = 8; +int stbi_write_tga_with_rle = 1; +int stbi_write_force_png_filter = -1; +#endif + +static int stbi__flip_vertically_on_write = 0; + +STBIWDEF void stbi_flip_vertically_on_write(int flag) +{ + stbi__flip_vertically_on_write = flag; +} + +typedef struct +{ + stbi_write_func *func; + void *context; + unsigned char buffer[64]; + int buf_used; +} stbi__write_context; + +// initialize a callback-based context +static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) +{ + s->func = c; + s->context = context; +} + +#ifndef STBI_WRITE_NO_STDIO + +static void stbi__stdio_write(void *context, void *data, int size) +{ + fwrite(data,1,size,(FILE*) context); +} + +#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) +#ifdef __cplusplus +#define STBIW_EXTERN extern "C" +#else +#define STBIW_EXTERN extern +#endif +STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); + +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbiw__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) + return 0; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + +static int stbi__start_write_file(stbi__write_context *s, const char *filename) +{ + FILE *f = stbiw__fopen(filename, "wb"); + stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); + return f != NULL; +} + +static void stbi__end_write_file(stbi__write_context *s) +{ + fclose((FILE *)s->context); +} + +#endif // !STBI_WRITE_NO_STDIO + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) +{ + while (*fmt) { + switch (*fmt++) { + case ' ': break; + case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); + s->func(s->context,&x,1); + break; } + case '2': { int x = va_arg(v,int); + unsigned char b[2]; + b[0] = STBIW_UCHAR(x); + b[1] = STBIW_UCHAR(x>>8); + s->func(s->context,b,2); + break; } + case '4': { stbiw_uint32 x = va_arg(v,int); + unsigned char b[4]; + b[0]=STBIW_UCHAR(x); + b[1]=STBIW_UCHAR(x>>8); + b[2]=STBIW_UCHAR(x>>16); + b[3]=STBIW_UCHAR(x>>24); + s->func(s->context,b,4); + break; } + default: + STBIW_ASSERT(0); + return; + } + } +} + +static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) +{ + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); +} + +static void stbiw__write_flush(stbi__write_context *s) +{ + if (s->buf_used) { + s->func(s->context, &s->buffer, s->buf_used); + s->buf_used = 0; + } +} + +static void stbiw__putc(stbi__write_context *s, unsigned char c) +{ + s->func(s->context, &c, 1); +} + +static void stbiw__write1(stbi__write_context *s, unsigned char a) +{ + if ((size_t)s->buf_used + 1 > sizeof(s->buffer)) + stbiw__write_flush(s); + s->buffer[s->buf_used++] = a; +} + +static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) +{ + int n; + if ((size_t)s->buf_used + 3 > sizeof(s->buffer)) + stbiw__write_flush(s); + n = s->buf_used; + s->buf_used = n+3; + s->buffer[n+0] = a; + s->buffer[n+1] = b; + s->buffer[n+2] = c; +} + +static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) +{ + unsigned char bg[3] = { 255, 0, 255}, px[3]; + int k; + + if (write_alpha < 0) + stbiw__write1(s, d[comp - 1]); + + switch (comp) { + case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case + case 1: + if (expand_mono) + stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp + else + stbiw__write1(s, d[0]); // monochrome TGA + break; + case 4: + if (!write_alpha) { + // composite against pink background + for (k = 0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; + stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); + break; + } + if (write_alpha > 0) + stbiw__write1(s, d[comp - 1]); +} + +static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) +{ + stbiw_uint32 zero = 0; + int i,j, j_end; + + if (y <= 0) + return; + + if (stbi__flip_vertically_on_write) + vdir *= -1; + + if (vdir < 0) { + j_end = -1; j = y-1; + } else { + j_end = y; j = 0; + } + + for (; j != j_end; j += vdir) { + for (i=0; i < x; ++i) { + unsigned char *d = (unsigned char *) data + (j*x+i)*comp; + stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); + } + stbiw__write_flush(s); + s->func(s->context, &zero, scanline_pad); + } +} + +static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) +{ + if (y < 0 || x < 0) { + return 0; + } else { + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); + stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); + return 1; + } +} + +static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) +{ + if (comp != 4) { + // write RGB bitmap + int pad = (-x*3) & 3; + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header + } else { + // RGBA bitmaps need a v4 header + // use BI_BITFIELDS mode with 32bpp and alpha mask + // (straight BI_RGB with alpha mask doesn't work in most readers) + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0, + "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444", + 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header + 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header + } +} + +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_bmp_core(&s, x, y, comp, data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_bmp_core(&s, x, y, comp, data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif //!STBI_WRITE_NO_STDIO + +static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) +{ + int has_alpha = (comp == 2 || comp == 4); + int colorbytes = has_alpha ? comp-1 : comp; + int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 + + if (y < 0 || x < 0) + return 0; + + if (!stbi_write_tga_with_rle) { + return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, + "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); + } else { + int i,j,k; + int jend, jdir; + + stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); + + if (stbi__flip_vertically_on_write) { + j = 0; + jend = y; + jdir = 1; + } else { + j = y-1; + jend = -1; + jdir = -1; + } + for (; j != jend; j += jdir) { + unsigned char *row = (unsigned char *) data + j * x * comp; + int len; + + for (i = 0; i < x; i += len) { + unsigned char *begin = row + i * comp; + int diff = 1; + len = 1; + + if (i < x - 1) { + ++len; + diff = memcmp(begin, row + (i + 1) * comp, comp); + if (diff) { + const unsigned char *prev = begin; + for (k = i + 2; k < x && len < 128; ++k) { + if (memcmp(prev, row + k * comp, comp)) { + prev += comp; + ++len; + } else { + --len; + break; + } + } + } else { + for (k = i + 2; k < x && len < 128; ++k) { + if (!memcmp(begin, row + k * comp, comp)) { + ++len; + } else { + break; + } + } + } + } + + if (diff) { + unsigned char header = STBIW_UCHAR(len - 1); + stbiw__write1(s, header); + for (k = 0; k < len; ++k) { + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); + } + } else { + unsigned char header = STBIW_UCHAR(len - 129); + stbiw__write1(s, header); + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); + } + } + } + stbiw__write_flush(s); + } + return 1; +} + +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_tga_core(&s, x, y, comp, (void *) data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR writer +// by Baldur Karlsson + +#define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) + +#ifndef STBI_WRITE_NO_STDIO + +static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) +{ + int exponent; + float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); + + if (maxcomp < 1e-32f) { + rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; + } else { + float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; + + rgbe[0] = (unsigned char)(linear[0] * normalize); + rgbe[1] = (unsigned char)(linear[1] * normalize); + rgbe[2] = (unsigned char)(linear[2] * normalize); + rgbe[3] = (unsigned char)(exponent + 128); + } +} + +static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) +{ + unsigned char lengthbyte = STBIW_UCHAR(length+128); + STBIW_ASSERT(length+128 <= 255); + s->func(s->context, &lengthbyte, 1); + s->func(s->context, &databyte, 1); +} + +static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) +{ + unsigned char lengthbyte = STBIW_UCHAR(length); + STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code + s->func(s->context, &lengthbyte, 1); + s->func(s->context, data, length); +} + +static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) +{ + unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; + unsigned char rgbe[4]; + float linear[3]; + int x; + + scanlineheader[2] = (width&0xff00)>>8; + scanlineheader[3] = (width&0x00ff); + + /* skip RLE for images too small or large */ + if (width < 8 || width >= 32768) { + for (x=0; x < width; x++) { + switch (ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + s->func(s->context, rgbe, 4); + } + } else { + int c,r; + /* encode into scratch buffer */ + for (x=0; x < width; x++) { + switch(ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + scratch[x + width*0] = rgbe[0]; + scratch[x + width*1] = rgbe[1]; + scratch[x + width*2] = rgbe[2]; + scratch[x + width*3] = rgbe[3]; + } + + s->func(s->context, scanlineheader, 4); + + /* RLE each component separately */ + for (c=0; c < 4; c++) { + unsigned char *comp = &scratch[width*c]; + + x = 0; + while (x < width) { + // find first run + r = x; + while (r+2 < width) { + if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) + break; + ++r; + } + if (r+2 >= width) + r = width; + // dump up to first run + while (x < r) { + int len = r-x; + if (len > 128) len = 128; + stbiw__write_dump_data(s, len, &comp[x]); + x += len; + } + // if there's a run, output it + if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd + // find next byte after run + while (r < width && comp[r] == comp[x]) + ++r; + // output run up to r + while (x < r) { + int len = r-x; + if (len > 127) len = 127; + stbiw__write_run_data(s, len, comp[x]); + x += len; + } + } + } + } + } +} + +static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) +{ + if (y <= 0 || x <= 0 || data == NULL) + return 0; + else { + // Each component is stored separately. Allocate scratch space for full output scanline. + unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); + int i, len; + char buffer[128]; + char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; + s->func(s->context, header, sizeof(header)-1); + +#ifdef __STDC_LIB_EXT1__ + len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#else + len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#endif + s->func(s->context, buffer, len); + + for(i=0; i < y; i++) + stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)); + STBIW_FREE(scratch); + return 1; + } +} + +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_hdr_core(&s, x, y, comp, (float *) data); +} + +STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif // STBI_WRITE_NO_STDIO + + +////////////////////////////////////////////////////////////////////////////// +// +// PNG writer +// + +#ifndef STBIW_ZLIB_COMPRESS +// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() +#define stbiw__sbraw(a) ((int *) (void *) (a) - 2) +#define stbiw__sbm(a) stbiw__sbraw(a)[0] +#define stbiw__sbn(a) stbiw__sbraw(a)[1] + +#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) +#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) +#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) + +#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) +#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) +#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) + +static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) +{ + int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; + void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); + STBIW_ASSERT(p); + if (p) { + if (!*arr) ((int *) p)[1] = 0; + *arr = (void *) ((int *) p + 2); + stbiw__sbm(*arr) = m; + } + return *arr; +} + +static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) +{ + while (*bitcount >= 8) { + stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; +} + +static int stbiw__zlib_bitrev(int code, int codebits) +{ + int res=0; + while (codebits--) { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; +} + +static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) +{ + int i; + for (i=0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; +} + +static unsigned int stbiw__zhash(unsigned char *data) +{ + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; +} + +#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) +#define stbiw__zlib_add(code,codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) +#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) +// default huffman tables +#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) +#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) +#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) +#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) +#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) +#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) + +#define stbiw__ZHASH 16384 + +#endif // STBIW_ZLIB_COMPRESS + +STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +{ +#ifdef STBIW_ZLIB_COMPRESS + // user provided a zlib compress implementation, use that + return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality); +#else // use builtin + static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; + static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; + static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; + static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; + unsigned int bitbuf=0; + int i,j, bitcount=0; + unsigned char *out = NULL; + unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**)); + if (hash_table == NULL) + return NULL; + if (quality < 5) quality = 5; + + stbiw__sbpush(out, 0x78); // DEFLATE 32K window + stbiw__sbpush(out, 0x5e); // FLEVEL = 1 + stbiw__zlib_add(1,1); // BFINAL = 1 + stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman + + for (i=0; i < stbiw__ZHASH; ++i) + hash_table[i] = NULL; + + i=0; + while (i < data_len-3) { + // hash next 3 bytes of data to be compressed + int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32768) { // if entry lies within window + int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); + if (d >= best) { best=d; bestloc=hlist[j]; } + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { + STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); + stbiw__sbn(hash_table[h]) = quality; + } + stbiw__sbpush(hash_table[h],data+i); + + if (bestloc) { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); + hlist = hash_table[h]; + n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32767) { + int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); + if (e > best) { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } + + if (bestloc) { + int d = (int) (data+i - bestloc); // distance back + STBIW_ASSERT(d <= 32767 && best <= 258); + for (j=0; best > lengthc[j+1]-1; ++j); + stbiw__zlib_huff(j+257); + if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); + for (j=0; d > distc[j+1]-1; ++j); + stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); + if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); + i += best; + } else { + stbiw__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (;i < data_len; ++i) + stbiw__zlib_huffb(data[i]); + stbiw__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbiw__zlib_add(0,1); + + for (i=0; i < stbiw__ZHASH; ++i) + (void) stbiw__sbfree(hash_table[i]); + STBIW_FREE(hash_table); + + // store uncompressed instead if compression was worse + if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) { + stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1 + for (j = 0; j < data_len;) { + int blocklen = data_len - j; + if (blocklen > 32767) blocklen = 32767; + stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression + stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN + stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN + stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8)); + memcpy(out+stbiw__sbn(out), data+j, blocklen); + stbiw__sbn(out) += blocklen; + j += blocklen; + } + } + + { + // compute adler32 on input + unsigned int s1=1, s2=0; + int blocklen = (int) (data_len % 5552); + j=0; + while (j < data_len) { + for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; } + s1 %= 65521; s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s2)); + stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s1)); + } + *out_len = stbiw__sbn(out); + // make returned pointer freeable + STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); + return (unsigned char *) stbiw__sbraw(out); +#endif // STBIW_ZLIB_COMPRESS +} + +static unsigned int stbiw__crc32(unsigned char *buffer, int len) +{ +#ifdef STBIW_CRC32 + return STBIW_CRC32(buffer, len); +#else + static unsigned int crc_table[256] = + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + + unsigned int crc = ~0u; + int i; + for (i=0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; +#endif +} + +#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) +#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); +#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) + +static void stbiw__wpcrc(unsigned char **data, int len) +{ + unsigned int crc = stbiw__crc32(*data - len - 4, len+4); + stbiw__wp32(*data, crc); +} + +static unsigned char stbiw__paeth(int a, int b, int c) +{ + int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); + if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); + if (pb <= pc) return STBIW_UCHAR(b); + return STBIW_UCHAR(c); +} + +// @OPTIMIZE: provide an option that always forces left-predict or paeth predict +static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer) +{ + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = (y != 0) ? mapping : firstmap; + int i; + int type = mymap[filter_type]; + unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); + int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes; + + if (type==0) { + memcpy(line_buffer, z, width*n); + return; + } + + // first loop isn't optimized since it's just one pixel + for (i = 0; i < n; ++i) { + switch (type) { + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + } + switch (type) { + case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break; + case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break; + case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break; + case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; + } +} + +STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int force_filter = stbi_write_force_png_filter; + int ctype[5] = { -1, 0, 4, 2, 6 }; + unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; + unsigned char *out,*o, *filt, *zlib; + signed char *line_buffer; + int j,zlen; + + if (stride_bytes == 0) + stride_bytes = x * n; + + if (force_filter >= 5) { + force_filter = -1; + } + + filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; + line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } + for (j=0; j < y; ++j) { + int filter_type; + if (force_filter > -1) { + filter_type = force_filter; + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer); + } else { // Estimate the best filter by running through all of them: + int best_filter = 0, best_filter_val = 0x7fffffff, est, i; + for (filter_type = 0; filter_type < 5; filter_type++) { + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer); + + // Estimate the entropy of the line using this filter; the less, the better. + est = 0; + for (i = 0; i < x*n; ++i) { + est += abs((signed char) line_buffer[i]); + } + if (est < best_filter_val) { + best_filter_val = est; + best_filter = filter_type; + } + } + if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer); + filter_type = best_filter; + } + } + // when we get here, filter_type contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) filter_type; + STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); + } + STBIW_FREE(line_buffer); + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level); + STBIW_FREE(filt); + if (!zlib) return 0; + + // each tag requires 12 bytes of overhead + out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); + if (!out) return 0; + *out_len = 8 + 12+13 + 12+zlen + 12; + + o=out; + STBIW_MEMMOVE(o,sig,8); o+= 8; + stbiw__wp32(o, 13); // header length + stbiw__wptag(o, "IHDR"); + stbiw__wp32(o, x); + stbiw__wp32(o, y); + *o++ = 8; + *o++ = STBIW_UCHAR(ctype[n]); + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbiw__wpcrc(&o,13); + + stbiw__wp32(o, zlen); + stbiw__wptag(o, "IDAT"); + STBIW_MEMMOVE(o, zlib, zlen); + o += zlen; + STBIW_FREE(zlib); + stbiw__wpcrc(&o, zlen); + + stbiw__wp32(o,0); + stbiw__wptag(o, "IEND"); + stbiw__wpcrc(&o,0); + + STBIW_ASSERT(o == out + *out_len); + + return out; +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) +{ + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + + f = stbiw__fopen(filename, "wb"); + if (!f) { STBIW_FREE(png); return 0; } + fwrite(png, 1, len, f); + fclose(f); + STBIW_FREE(png); + return 1; +} +#endif + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) +{ + int len; + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + func(context, png, len); + STBIW_FREE(png); + return 1; +} + + +/* *************************************************************************** + * + * JPEG writer + * + * This is based on Jon Olick's jo_jpeg.cpp: + * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html + */ + +static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, + 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; + +static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { + int bitBuf = *bitBufP, bitCnt = *bitCntP; + bitCnt += bs[1]; + bitBuf |= bs[0] << (24 - bitCnt); + while(bitCnt >= 8) { + unsigned char c = (bitBuf >> 16) & 255; + stbiw__putc(s, c); + if(c == 255) { + stbiw__putc(s, 0); + } + bitBuf <<= 8; + bitCnt -= 8; + } + *bitBufP = bitBuf; + *bitCntP = bitCnt; +} + +static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { + float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; + float z1, z2, z3, z4, z5, z11, z13; + + float tmp0 = d0 + d7; + float tmp7 = d0 - d7; + float tmp1 = d1 + d6; + float tmp6 = d1 - d6; + float tmp2 = d2 + d5; + float tmp5 = d2 - d5; + float tmp3 = d3 + d4; + float tmp4 = d3 - d4; + + // Even part + float tmp10 = tmp0 + tmp3; // phase 2 + float tmp13 = tmp0 - tmp3; + float tmp11 = tmp1 + tmp2; + float tmp12 = tmp1 - tmp2; + + d0 = tmp10 + tmp11; // phase 3 + d4 = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781f; // c4 + d2 = tmp13 + z1; // phase 5 + d6 = tmp13 - z1; + + // Odd part + tmp10 = tmp4 + tmp5; // phase 2 + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + // The rotator is modified from fig 4-8 to avoid extra negations. + z5 = (tmp10 - tmp12) * 0.382683433f; // c6 + z2 = tmp10 * 0.541196100f + z5; // c2-c6 + z4 = tmp12 * 1.306562965f + z5; // c2+c6 + z3 = tmp11 * 0.707106781f; // c4 + + z11 = tmp7 + z3; // phase 5 + z13 = tmp7 - z3; + + *d5p = z13 + z2; // phase 6 + *d3p = z13 - z2; + *d1p = z11 + z4; + *d7p = z11 - z4; + + *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; +} + +static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { + int tmp1 = val < 0 ? -val : val; + val = val < 0 ? val-1 : val; + bits[1] = 1; + while(tmp1 >>= 1) { + ++bits[1]; + } + bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { + } + // end0pos = first element in reverse order !=0 + if(end0pos == 0) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + return DU[0]; + } + for(i = 1; i <= end0pos; ++i) { + int startpos = i; + int nrzeroes; + unsigned short bits[2]; + for (; DU[i]==0 && i<=end0pos; ++i) { + } + nrzeroes = i-startpos; + if ( nrzeroes >= 16 ) { + int lng = nrzeroes>>4; + int nrmarker; + for (nrmarker=1; nrmarker <= lng; ++nrmarker) + stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); + nrzeroes &= 15; + } + stbiw__jpg_calcBits(DU[i], bits); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); + } + if(end0pos != 63) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + } + return DU[0]; +} + +static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { + // Constants that don't pollute global namespace + static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; + static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; + static const unsigned char std_ac_luminance_values[] = { + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; + static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; + static const unsigned char std_ac_chrominance_values[] = { + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + // Huffman tables + static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; + static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; + static const unsigned short YAC_HT[256][2] = { + {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const unsigned short UVAC_HT[256][2] = { + {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, + 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; + static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; + static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, + 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; + + int row, col, i, k, subsample; + float fdtbl_Y[64], fdtbl_UV[64]; + unsigned char YTable[64], UVTable[64]; + + if(!data || !width || !height || comp > 4 || comp < 1) { + return 0; + } + + quality = quality ? quality : 90; + subsample = quality <= 90 ? 1 : 0; + quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; + quality = quality < 50 ? 5000 / quality : 200 - quality * 2; + + for(i = 0; i < 64; ++i) { + int uvti, yti = (YQT[i]*quality+50)/100; + YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); + uvti = (UVQT[i]*quality+50)/100; + UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); + } + + for(row = 0, k = 0; row < 8; ++row) { + for(col = 0; col < 8; ++col, ++k) { + fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + } + } + + // Write Headers + { + static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; + static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; + const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width), + 3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; + s->func(s->context, (void*)head0, sizeof(head0)); + s->func(s->context, (void*)YTable, sizeof(YTable)); + stbiw__putc(s, 1); + s->func(s->context, UVTable, sizeof(UVTable)); + s->func(s->context, (void*)head1, sizeof(head1)); + s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); + s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); + stbiw__putc(s, 0x10); // HTYACinfo + s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); + s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); + stbiw__putc(s, 1); // HTUDCinfo + s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); + stbiw__putc(s, 0x11); // HTUACinfo + s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); + s->func(s->context, (void*)head2, sizeof(head2)); + } + + // Encode 8x8 macroblocks + { + static const unsigned short fillBits[] = {0x7F, 7}; + int DCY=0, DCU=0, DCV=0; + int bitBuf=0, bitCnt=0; + // comp == 2 is grey+alpha (alpha is ignored) + int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; + const unsigned char *dataR = (const unsigned char *)data; + const unsigned char *dataG = dataR + ofsG; + const unsigned char *dataB = dataR + ofsB; + int x, y, pos; + if(subsample) { + for(y = 0; y < height; y += 16) { + for(x = 0; x < width; x += 16) { + float Y[256], U[256], V[256]; + for(row = y, pos = 0; row < y+16; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+16; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + + // subsample U,V + { + float subU[64], subV[64]; + int yy, xx; + for(yy = 0, pos = 0; yy < 8; ++yy) { + for(xx = 0; xx < 8; ++xx, ++pos) { + int j = yy*32+xx*2; + subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f; + subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f; + } + } + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + } else { + for(y = 0; y < height; y += 8) { + for(x = 0; x < width; x += 8) { + float Y[64], U[64], V[64]; + for(row = y, pos = 0; row < y+8; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+8; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + + // Do the bit alignment of the EOI marker + stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); + } + + // EOI + stbiw__putc(s, 0xFF); + stbiw__putc(s, 0xD9); + + return 1; +} + +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s = { 0 }; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); +} + + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s = { 0 }; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + 1.16 (2021-07-11) + make Deflate code emit uncompressed blocks when it would otherwise expand + support writing BMPs with alpha channel + 1.15 (2020-07-13) unknown + 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels + 1.13 + 1.12 + 1.11 (2019-08-11) + + 1.10 (2019-02-07) + support utf8 filenames in Windows; fix warnings and platform ifdefs + 1.09 (2018-02-11) + fix typo in zlib quality API, improve STB_I_W_STATIC in C++ + 1.08 (2018-01-29) + add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter + 1.07 (2017-07-24) + doc fix + 1.06 (2017-07-23) + writing JPEG (using Jon Olick's code) + 1.05 ??? + 1.04 (2017-03-03) + monochrome BMP expansion + 1.03 ??? + 1.02 (2016-04-02) + avoid allocating large structures on the stack + 1.01 (2016-01-16) + STBIW_REALLOC_SIZED: support allocators with no realloc support + avoid race-condition in crc initialization + minor compile issues + 1.00 (2015-09-14) + installable file IO function + 0.99 (2015-09-13) + warning fixes; TGA rle support + 0.98 (2015-04-08) + added STBIW_MALLOC, STBIW_ASSERT etc + 0.97 (2015-01-18) + fixed HDR asserts, rewrote HDR rle logic + 0.96 (2015-01-17) + add HDR output + fix monochrome BMP + 0.95 (2014-08-17) + add monochrome TGA output + 0.94 (2014-05-31) + rename private functions to avoid conflicts with stb_image.h + 0.93 (2014-05-27) + warning fixes + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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/tools/testloradec.grc b/tools/testloradec.grc new file mode 100644 index 0000000..f9a5235 --- /dev/null +++ b/tools/testloradec.grc @@ -0,0 +1,1230 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: testloradec + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: Not titled yet + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: FFTSIZE + id: variable + parameters: + comment: '' + value: '1024' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [416, 44.0] + rotation: 0 + state: true +- name: blocks_complex_to_float_0 + id: blocks_complex_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1264, 48.0] + rotation: 0 + state: true +- name: blocks_complex_to_mag_squared_0 + id: blocks_complex_to_mag_squared + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1064, 208.0] + rotation: 0 + state: enabled +- name: blocks_correctiq_0 + id: blocks_correctiq + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [280, 712.0] + rotation: 0 + state: disabled +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /tmp/test.txt + type: float + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [808, 524.0] + rotation: 0 + state: true +- name: blocks_file_sink_1 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /tmp/samplelog.dat + type: float + unbuffered: 'False' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1744, 272.0] + rotation: 0 + state: enabled +- name: blocks_file_sink_1_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /tmp/samplelog_I.dat + type: float + unbuffered: 'False' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1760, 40.0] + rotation: 0 + state: enabled +- name: blocks_file_sink_1_0_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /tmp/samplelog_Q.dat + type: float + unbuffered: 'False' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1736, 160.0] + rotation: 0 + state: enabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + log_level: info + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1512, 608.0] + rotation: 0 + state: true +- name: blocks_nlog10_ff_0 + id: blocks_nlog10_ff + parameters: + affinity: '' + alias: '' + comment: '' + k: '0' + maxoutbuf: '0' + minoutbuf: '0' + n: '1' + vlen: FFTSIZE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1288, 140.0] + rotation: 0 + state: enabled +- name: blocks_stream_to_vector_0 + id: blocks_stream_to_vector + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + num_items: FFTSIZE + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [568, 176.0] + rotation: 0 + state: enabled +- name: fft_vxx_0 + id: fft_vxx + parameters: + affinity: '' + alias: '' + comment: '' + fft_size: FFTSIZE + forward: 'True' + maxoutbuf: '0' + minoutbuf: '0' + nthreads: '1' + shift: 'True' + type: complex + window: window.blackmanharris(FFTSIZE) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [808, 124.0] + rotation: 0 + state: enabled +- name: lora_sdr_crc_verif_0 + id: lora_sdr_crc_verif + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + output_crc_check: 'False' + print_rx_msg: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1152, 592.0] + rotation: 0 + state: true +- name: lora_sdr_deinterleaver_0 + id: lora_sdr_deinterleaver + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + soft_decoding: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1256, 372.0] + rotation: 0 + state: true +- name: lora_sdr_dewhitening_0 + id: lora_sdr_dewhitening + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1296, 480.0] + rotation: 0 + state: true +- name: lora_sdr_fft_demod_0 + id: lora_sdr_fft_demod + parameters: + affinity: '' + alias: '' + comment: '' + max_log_approx: 'True' + maxoutbuf: '0' + minoutbuf: '0' + soft_decoding: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [816, 372.0] + rotation: 0 + state: true +- name: lora_sdr_frame_sync_0 + id: lora_sdr_frame_sync + parameters: + affinity: '' + alias: '' + bandwidth: '125000' + center_freq: '903900000' + comment: '' + impl_head: 'False' + maxoutbuf: '0' + minoutbuf: '0' + os_factor: '20' + preamb_len: '8' + sf: '7' + show_log_port: 'True' + sync_word: '0x34' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [624, 404.0] + rotation: 0 + state: true +- name: lora_sdr_gray_mapping_0 + id: lora_sdr_gray_mapping + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + soft_decoding: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1040, 372.0] + rotation: 0 + state: true +- name: lora_sdr_hamming_dec_0 + id: lora_sdr_hamming_dec + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + soft_decoding: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1472, 372.0] + rotation: 0 + state: true +- name: lora_sdr_header_decoder_0 + id: lora_sdr_header_decoder + parameters: + affinity: '' + alias: '' + comment: '' + cr: '3' + has_crc: 'False' + impl_head: 'False' + ldro: '2' + maxoutbuf: '0' + minoutbuf: '0' + pay_len: '255' + print_header: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1016, 476.0] + rotation: 0 + state: true +- name: osmosdr_source_0 + id: osmosdr_source + parameters: + affinity: '' + alias: '' + ant0: '' + ant1: '' + ant10: '' + ant11: '' + ant12: '' + ant13: '' + ant14: '' + ant15: '' + ant16: '' + ant17: '' + ant18: '' + ant19: '' + ant2: '' + ant20: '' + ant21: '' + ant22: '' + ant23: '' + ant24: '' + ant25: '' + ant26: '' + ant27: '' + ant28: '' + ant29: '' + ant3: '' + ant30: '' + ant31: '' + ant4: '' + ant5: '' + ant6: '' + ant7: '' + ant8: '' + ant9: '' + args: '"airspy=0"' + bb_gain0: '10' + bb_gain1: '20' + bb_gain10: '20' + bb_gain11: '20' + bb_gain12: '20' + bb_gain13: '20' + bb_gain14: '20' + bb_gain15: '20' + bb_gain16: '20' + bb_gain17: '20' + bb_gain18: '20' + bb_gain19: '20' + bb_gain2: '20' + bb_gain20: '20' + bb_gain21: '20' + bb_gain22: '20' + bb_gain23: '20' + bb_gain24: '20' + bb_gain25: '20' + bb_gain26: '20' + bb_gain27: '20' + bb_gain28: '20' + bb_gain29: '20' + bb_gain3: '20' + bb_gain30: '20' + bb_gain31: '20' + bb_gain4: '20' + bb_gain5: '20' + bb_gain6: '20' + bb_gain7: '20' + bb_gain8: '20' + bb_gain9: '20' + bw0: '0' + bw1: '0' + bw10: '0' + bw11: '0' + bw12: '0' + bw13: '0' + bw14: '0' + bw15: '0' + bw16: '0' + bw17: '0' + bw18: '0' + bw19: '0' + bw2: '0' + bw20: '0' + bw21: '0' + bw22: '0' + bw23: '0' + bw24: '0' + bw25: '0' + bw26: '0' + bw27: '0' + bw28: '0' + bw29: '0' + bw3: '0' + bw30: '0' + bw31: '0' + bw4: '0' + bw5: '0' + bw6: '0' + bw7: '0' + bw8: '0' + bw9: '0' + clock_source0: '' + clock_source1: '' + clock_source2: '' + clock_source3: '' + clock_source4: '' + clock_source5: '' + clock_source6: '' + clock_source7: '' + comment: '' + corr0: '0' + corr1: '0' + corr10: '0' + corr11: '0' + corr12: '0' + corr13: '0' + corr14: '0' + corr15: '0' + corr16: '0' + corr17: '0' + corr18: '0' + corr19: '0' + corr2: '0' + corr20: '0' + corr21: '0' + corr22: '0' + corr23: '0' + corr24: '0' + corr25: '0' + corr26: '0' + corr27: '0' + corr28: '0' + corr29: '0' + corr3: '0' + corr30: '0' + corr31: '0' + corr4: '0' + corr5: '0' + corr6: '0' + corr7: '0' + corr8: '0' + corr9: '0' + dc_offset_mode0: '0' + dc_offset_mode1: '0' + dc_offset_mode10: '0' + dc_offset_mode11: '0' + dc_offset_mode12: '0' + dc_offset_mode13: '0' + dc_offset_mode14: '0' + dc_offset_mode15: '0' + dc_offset_mode16: '0' + dc_offset_mode17: '0' + dc_offset_mode18: '0' + dc_offset_mode19: '0' + dc_offset_mode2: '0' + dc_offset_mode20: '0' + dc_offset_mode21: '0' + dc_offset_mode22: '0' + dc_offset_mode23: '0' + dc_offset_mode24: '0' + dc_offset_mode25: '0' + dc_offset_mode26: '0' + dc_offset_mode27: '0' + dc_offset_mode28: '0' + dc_offset_mode29: '0' + dc_offset_mode3: '0' + dc_offset_mode30: '0' + dc_offset_mode31: '0' + dc_offset_mode4: '0' + dc_offset_mode5: '0' + dc_offset_mode6: '0' + dc_offset_mode7: '0' + dc_offset_mode8: '0' + dc_offset_mode9: '0' + freq0: '903900000' + freq1: 100e6 + freq10: 100e6 + freq11: 100e6 + freq12: 100e6 + freq13: 100e6 + freq14: 100e6 + freq15: 100e6 + freq16: 100e6 + freq17: 100e6 + freq18: 100e6 + freq19: 100e6 + freq2: 100e6 + freq20: 100e6 + freq21: 100e6 + freq22: 100e6 + freq23: 100e6 + freq24: 100e6 + freq25: 100e6 + freq26: 100e6 + freq27: 100e6 + freq28: 100e6 + freq29: 100e6 + freq3: 100e6 + freq30: 100e6 + freq31: 100e6 + freq4: 100e6 + freq5: 100e6 + freq6: 100e6 + freq7: 100e6 + freq8: 100e6 + freq9: 100e6 + gain0: '10' + gain1: '10' + gain10: '10' + gain11: '10' + gain12: '10' + gain13: '10' + gain14: '10' + gain15: '10' + gain16: '10' + gain17: '10' + gain18: '10' + gain19: '10' + gain2: '10' + gain20: '10' + gain21: '10' + gain22: '10' + gain23: '10' + gain24: '10' + gain25: '10' + gain26: '10' + gain27: '10' + gain28: '10' + gain29: '10' + gain3: '10' + gain30: '10' + gain31: '10' + gain4: '10' + gain5: '10' + gain6: '10' + gain7: '10' + gain8: '10' + gain9: '10' + gain_mode0: 'False' + gain_mode1: 'False' + gain_mode10: 'False' + gain_mode11: 'False' + gain_mode12: 'False' + gain_mode13: 'False' + gain_mode14: 'False' + gain_mode15: 'False' + gain_mode16: 'False' + gain_mode17: 'False' + gain_mode18: 'False' + gain_mode19: 'False' + gain_mode2: 'False' + gain_mode20: 'False' + gain_mode21: 'False' + gain_mode22: 'False' + gain_mode23: 'False' + gain_mode24: 'False' + gain_mode25: 'False' + gain_mode26: 'False' + gain_mode27: 'False' + gain_mode28: 'False' + gain_mode29: 'False' + gain_mode3: 'False' + gain_mode30: 'False' + gain_mode31: 'False' + gain_mode4: 'False' + gain_mode5: 'False' + gain_mode6: 'False' + gain_mode7: 'False' + gain_mode8: 'False' + gain_mode9: 'False' + if_gain0: '10' + if_gain1: '20' + if_gain10: '20' + if_gain11: '20' + if_gain12: '20' + if_gain13: '20' + if_gain14: '20' + if_gain15: '20' + if_gain16: '20' + if_gain17: '20' + if_gain18: '20' + if_gain19: '20' + if_gain2: '20' + if_gain20: '20' + if_gain21: '20' + if_gain22: '20' + if_gain23: '20' + if_gain24: '20' + if_gain25: '20' + if_gain26: '20' + if_gain27: '20' + if_gain28: '20' + if_gain29: '20' + if_gain3: '20' + if_gain30: '20' + if_gain31: '20' + if_gain4: '20' + if_gain5: '20' + if_gain6: '20' + if_gain7: '20' + if_gain8: '20' + if_gain9: '20' + iq_balance_mode0: '0' + iq_balance_mode1: '0' + iq_balance_mode10: '0' + iq_balance_mode11: '0' + iq_balance_mode12: '0' + iq_balance_mode13: '0' + iq_balance_mode14: '0' + iq_balance_mode15: '0' + iq_balance_mode16: '0' + iq_balance_mode17: '0' + iq_balance_mode18: '0' + iq_balance_mode19: '0' + iq_balance_mode2: '0' + iq_balance_mode20: '0' + iq_balance_mode21: '0' + iq_balance_mode22: '0' + iq_balance_mode23: '0' + iq_balance_mode24: '0' + iq_balance_mode25: '0' + iq_balance_mode26: '0' + iq_balance_mode27: '0' + iq_balance_mode28: '0' + iq_balance_mode29: '0' + iq_balance_mode3: '0' + iq_balance_mode30: '0' + iq_balance_mode31: '0' + iq_balance_mode4: '0' + iq_balance_mode5: '0' + iq_balance_mode6: '0' + iq_balance_mode7: '0' + iq_balance_mode8: '0' + iq_balance_mode9: '0' + maxoutbuf: '0' + minoutbuf: '0' + nchan: '1' + num_mboards: '1' + sample_rate: '6000000' + sync: sync + time_source0: '' + time_source1: '' + time_source2: '' + time_source3: '' + time_source4: '' + time_source5: '' + time_source6: '' + time_source7: '' + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [88, 188.0] + rotation: 0 + state: enabled +- name: qtgui_waterfall_sink_x_0 + id: qtgui_waterfall_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + axislabels: 'True' + bw: 1e6 + color1: '0' + color10: '0' + color2: '0' + color3: '0' + color4: '0' + color5: '0' + color6: '0' + color7: '0' + color8: '0' + color9: '0' + comment: '' + fc: '903900000' + fftsize: '4096' + freqhalf: 'True' + grid: 'False' + gui_hint: '' + int_max: '10' + int_min: '-140' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + showports: 'False' + type: complex + update_time: '0.001' + wintype: window.WIN_BLACKMAN_hARRIS + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [592, 644.0] + rotation: 0 + state: enabled +- name: rational_resampler_xxx_0 + id: rational_resampler_xxx + parameters: + affinity: '' + alias: '' + comment: '' + decim: '16' + fbw: '0' + interp: '1' + maxoutbuf: '0' + minoutbuf: '0' + taps: '[]' + type: ccc + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [416, 216.0] + rotation: 0 + state: disabled +- name: rtlsdr_source_0 + id: rtlsdr_source + parameters: + affinity: '' + alias: '' + ant0: '' + ant1: '' + ant10: '' + ant11: '' + ant12: '' + ant13: '' + ant14: '' + ant15: '' + ant16: '' + ant17: '' + ant18: '' + ant19: '' + ant2: '' + ant20: '' + ant21: '' + ant22: '' + ant23: '' + ant24: '' + ant25: '' + ant26: '' + ant27: '' + ant28: '' + ant29: '' + ant3: '' + ant30: '' + ant31: '' + ant4: '' + ant5: '' + ant6: '' + ant7: '' + ant8: '' + ant9: '' + args: '""' + bb_gain0: '4' + bb_gain1: '20' + bb_gain10: '20' + bb_gain11: '20' + bb_gain12: '20' + bb_gain13: '20' + bb_gain14: '20' + bb_gain15: '20' + bb_gain16: '20' + bb_gain17: '20' + bb_gain18: '20' + bb_gain19: '20' + bb_gain2: '20' + bb_gain20: '20' + bb_gain21: '20' + bb_gain22: '20' + bb_gain23: '20' + bb_gain24: '20' + bb_gain25: '20' + bb_gain26: '20' + bb_gain27: '20' + bb_gain28: '20' + bb_gain29: '20' + bb_gain3: '20' + bb_gain30: '20' + bb_gain31: '20' + bb_gain4: '20' + bb_gain5: '20' + bb_gain6: '20' + bb_gain7: '20' + bb_gain8: '20' + bb_gain9: '20' + bw0: '0' + bw1: '0' + bw10: '0' + bw11: '0' + bw12: '0' + bw13: '0' + bw14: '0' + bw15: '0' + bw16: '0' + bw17: '0' + bw18: '0' + bw19: '0' + bw2: '0' + bw20: '0' + bw21: '0' + bw22: '0' + bw23: '0' + bw24: '0' + bw25: '0' + bw26: '0' + bw27: '0' + bw28: '0' + bw29: '0' + bw3: '0' + bw30: '0' + bw31: '0' + bw4: '0' + bw5: '0' + bw6: '0' + bw7: '0' + bw8: '0' + bw9: '0' + clock_source0: '' + clock_source1: '' + clock_source2: '' + clock_source3: '' + clock_source4: '' + clock_source5: '' + clock_source6: '' + clock_source7: '' + comment: '' + corr0: '0' + corr1: '0' + corr10: '0' + corr11: '0' + corr12: '0' + corr13: '0' + corr14: '0' + corr15: '0' + corr16: '0' + corr17: '0' + corr18: '0' + corr19: '0' + corr2: '0' + corr20: '0' + corr21: '0' + corr22: '0' + corr23: '0' + corr24: '0' + corr25: '0' + corr26: '0' + corr27: '0' + corr28: '0' + corr29: '0' + corr3: '0' + corr30: '0' + corr31: '0' + corr4: '0' + corr5: '0' + corr6: '0' + corr7: '0' + corr8: '0' + corr9: '0' + dc_offset_mode0: '0' + dc_offset_mode1: '0' + dc_offset_mode10: '0' + dc_offset_mode11: '0' + dc_offset_mode12: '0' + dc_offset_mode13: '0' + dc_offset_mode14: '0' + dc_offset_mode15: '0' + dc_offset_mode16: '0' + dc_offset_mode17: '0' + dc_offset_mode18: '0' + dc_offset_mode19: '0' + dc_offset_mode2: '0' + dc_offset_mode20: '0' + dc_offset_mode21: '0' + dc_offset_mode22: '0' + dc_offset_mode23: '0' + dc_offset_mode24: '0' + dc_offset_mode25: '0' + dc_offset_mode26: '0' + dc_offset_mode27: '0' + dc_offset_mode28: '0' + dc_offset_mode29: '0' + dc_offset_mode3: '0' + dc_offset_mode30: '0' + dc_offset_mode31: '0' + dc_offset_mode4: '0' + dc_offset_mode5: '0' + dc_offset_mode6: '0' + dc_offset_mode7: '0' + dc_offset_mode8: '0' + dc_offset_mode9: '0' + freq0: 903.9e6 + freq1: 100e6 + freq10: 100e6 + freq11: 100e6 + freq12: 100e6 + freq13: 100e6 + freq14: 100e6 + freq15: 100e6 + freq16: 100e6 + freq17: 100e6 + freq18: 100e6 + freq19: 100e6 + freq2: 100e6 + freq20: 100e6 + freq21: 100e6 + freq22: 100e6 + freq23: 100e6 + freq24: 100e6 + freq25: 100e6 + freq26: 100e6 + freq27: 100e6 + freq28: 100e6 + freq29: 100e6 + freq3: 100e6 + freq30: 100e6 + freq31: 100e6 + freq4: 100e6 + freq5: 100e6 + freq6: 100e6 + freq7: 100e6 + freq8: 100e6 + freq9: 100e6 + gain0: '4' + gain1: '10' + gain10: '10' + gain11: '10' + gain12: '10' + gain13: '10' + gain14: '10' + gain15: '10' + gain16: '10' + gain17: '10' + gain18: '10' + gain19: '10' + gain2: '10' + gain20: '10' + gain21: '10' + gain22: '10' + gain23: '10' + gain24: '10' + gain25: '10' + gain26: '10' + gain27: '10' + gain28: '10' + gain29: '10' + gain3: '10' + gain30: '10' + gain31: '10' + gain4: '10' + gain5: '10' + gain6: '10' + gain7: '10' + gain8: '10' + gain9: '10' + gain_mode0: 'False' + gain_mode1: 'False' + gain_mode10: 'False' + gain_mode11: 'False' + gain_mode12: 'False' + gain_mode13: 'False' + gain_mode14: 'False' + gain_mode15: 'False' + gain_mode16: 'False' + gain_mode17: 'False' + gain_mode18: 'False' + gain_mode19: 'False' + gain_mode2: 'False' + gain_mode20: 'False' + gain_mode21: 'False' + gain_mode22: 'False' + gain_mode23: 'False' + gain_mode24: 'False' + gain_mode25: 'False' + gain_mode26: 'False' + gain_mode27: 'False' + gain_mode28: 'False' + gain_mode29: 'False' + gain_mode3: 'False' + gain_mode30: 'False' + gain_mode31: 'False' + gain_mode4: 'False' + gain_mode5: 'False' + gain_mode6: 'False' + gain_mode7: 'False' + gain_mode8: 'False' + gain_mode9: 'False' + if_gain0: '4' + if_gain1: '20' + if_gain10: '20' + if_gain11: '20' + if_gain12: '20' + if_gain13: '20' + if_gain14: '20' + if_gain15: '20' + if_gain16: '20' + if_gain17: '20' + if_gain18: '20' + if_gain19: '20' + if_gain2: '20' + if_gain20: '20' + if_gain21: '20' + if_gain22: '20' + if_gain23: '20' + if_gain24: '20' + if_gain25: '20' + if_gain26: '20' + if_gain27: '20' + if_gain28: '20' + if_gain29: '20' + if_gain3: '20' + if_gain30: '20' + if_gain31: '20' + if_gain4: '20' + if_gain5: '20' + if_gain6: '20' + if_gain7: '20' + if_gain8: '20' + if_gain9: '20' + iq_balance_mode0: '0' + iq_balance_mode1: '0' + iq_balance_mode10: '0' + iq_balance_mode11: '0' + iq_balance_mode12: '0' + iq_balance_mode13: '0' + iq_balance_mode14: '0' + iq_balance_mode15: '0' + iq_balance_mode16: '0' + iq_balance_mode17: '0' + iq_balance_mode18: '0' + iq_balance_mode19: '0' + iq_balance_mode2: '0' + iq_balance_mode20: '0' + iq_balance_mode21: '0' + iq_balance_mode22: '0' + iq_balance_mode23: '0' + iq_balance_mode24: '0' + iq_balance_mode25: '0' + iq_balance_mode26: '0' + iq_balance_mode27: '0' + iq_balance_mode28: '0' + iq_balance_mode29: '0' + iq_balance_mode3: '0' + iq_balance_mode30: '0' + iq_balance_mode31: '0' + iq_balance_mode4: '0' + iq_balance_mode5: '0' + iq_balance_mode6: '0' + iq_balance_mode7: '0' + iq_balance_mode8: '0' + iq_balance_mode9: '0' + maxoutbuf: '0' + minoutbuf: '0' + nchan: '1' + num_mboards: '1' + sample_rate: 3e6 + sync: sync + time_source0: '' + time_source1: '' + time_source2: '' + time_source3: '' + time_source4: '' + time_source5: '' + time_source6: '' + time_source7: '' + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [128, 468.0] + rotation: 0 + state: disabled +- name: soapy_hackrf_source_0 + id: soapy_hackrf_source + parameters: + affinity: '' + alias: '' + amp: 'False' + bandwidth: '0' + center_freq: 903.9e6 + comment: '' + dev_args: '' + gain: '16' + maxoutbuf: '0' + minoutbuf: '0' + samp_rate: 3e6 + type: fc32 + vga: '16' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [80, 780.0] + rotation: 0 + state: disabled + +connections: +- [blocks_complex_to_float_0, '0', blocks_file_sink_1_0, '0'] +- [blocks_complex_to_float_0, '1', blocks_file_sink_1_0_0, '0'] +- [blocks_complex_to_mag_squared_0, '0', blocks_nlog10_ff_0, '0'] +- [blocks_correctiq_0, '0', blocks_stream_to_vector_0, '0'] +- [blocks_correctiq_0, '0', lora_sdr_frame_sync_0, '0'] +- [blocks_correctiq_0, '0', qtgui_waterfall_sink_x_0, '0'] +- [blocks_nlog10_ff_0, '0', blocks_file_sink_1, '0'] +- [blocks_stream_to_vector_0, '0', fft_vxx_0, '0'] +- [fft_vxx_0, '0', blocks_complex_to_float_0, '0'] +- [fft_vxx_0, '0', blocks_complex_to_mag_squared_0, '0'] +- [lora_sdr_crc_verif_0, msg, blocks_message_debug_0, print] +- [lora_sdr_deinterleaver_0, '0', lora_sdr_hamming_dec_0, '0'] +- [lora_sdr_dewhitening_0, '0', lora_sdr_crc_verif_0, '0'] +- [lora_sdr_fft_demod_0, '0', lora_sdr_gray_mapping_0, '0'] +- [lora_sdr_frame_sync_0, '0', lora_sdr_fft_demod_0, '0'] +- [lora_sdr_frame_sync_0, '1', blocks_file_sink_0, '0'] +- [lora_sdr_gray_mapping_0, '0', lora_sdr_deinterleaver_0, '0'] +- [lora_sdr_hamming_dec_0, '0', lora_sdr_header_decoder_0, '0'] +- [lora_sdr_header_decoder_0, '0', lora_sdr_dewhitening_0, '0'] +- [lora_sdr_header_decoder_0, frame_info, lora_sdr_frame_sync_0, frame_info] +- [osmosdr_source_0, '0', blocks_stream_to_vector_0, '0'] +- [osmosdr_source_0, '0', lora_sdr_frame_sync_0, '0'] +- [osmosdr_source_0, '0', qtgui_waterfall_sink_x_0, '0'] +- [rtlsdr_source_0, '0', blocks_stream_to_vector_0, '0'] +- [rtlsdr_source_0, '0', lora_sdr_frame_sync_0, '0'] +- [rtlsdr_source_0, '0', qtgui_waterfall_sink_x_0, '0'] +- [soapy_hackrf_source_0, '0', blocks_correctiq_0, '0'] + +metadata: + file_format: 1 + grc_version: 3.10.7.0

    mWK_7cv*XT(TWXh%B}Rs` zb8vu1hp38dwBN&TvESNTYqABApMbp@1#WbU=I`<_UH@Nu~P`U!Xvm>2|J9pIWq zm4ioNo#b?TAUBok8;K_Jno#k()$M^{7{>5zC>rVoZ%}S8IQqX()Z`(UoTYk8tLSwuF|x5E;4;VDl*0w5&=Jilb5#d25>JT9iR$$ z>^I7St@i>bFATC)ZOl{5tt9PZb`Pt*1wNgLX4I81BO}^_|Ni}JG(aK}2k5`t7n)gp zMga|RefiVjq`sr2dA?&-yf$i9kbAtX1pe=Lc}|Z*4OG_RnN(QjVqd?y_Nyjfko$XY z;7t{zY*4GO@Q5`&te?H^;r0OHl!8kKargT}%^gtQ_%rNJlWJF37ndtOkY$G=saOoY zzg1f_GKhp{ai)%lY}xEy?Qyns*lyGqgH6g;gMN0Xcev%!^r?FoSGf7~y+q(sR(M_t za?zF74*z%_GmrWuN*}3_L>2k${;}R80aDH5N415W@@ke|_jw+7C=_`a9HA@hD)l(I6n*X+4$M0Q#%nYJJO@|Us2+$ z_&QUoHs~uo&TtKHo6qFE?O*XfAjO=%t^2bsN>cimczZ`*TvYM--I0!gi&G!Py0R2)5K=#Bj?puh+m%u`2E}YmkrbPzQ^*OH0!7>Lx$EZH}yiJ_by9O z8SN)LDAv%E;@?<3zbWVH54m^aj2#Vs;aC4ugtsgj1Dnf5W5)LRkM~s<(8p`hFl;TL zr?P2uk!-)MU;Tm)7Ur?v0)65pcUufSq9rRv9{II0pyWAv$(;NpY&Uqh#;~JODT+d= zW7Fbp>JWOSbm%?BDbM5B2~^9~wf5SnffJsawPH;BB*C1UZac!cj$!BZ1`{-%XLxuw z&BCRhNbpsDG{f^aUidWv$cA`FMDmpqj8pqr%BEF?+gHkRIWK>p-^nRUCxe}ZkGG8B zjVC%9SKJptg3*LB%$m8OhOD{Z2I~M*-f4o@_+C!{O4xV0BfZ>Z-ItnC8N z135UfJ*rxzv$CNJ(^Z*@DPyMRx}sI4b)5~%J#@4Q%=;BkWgQh*Aa-NuWl!fg>iQ)| z(PVj=!%0q19~s?6TP%|XKInz;Xk_{o^KRsDE3oW^GOJXY&!w%z!zJ36l;}J7%=gj_ z`@TEq2tm+7;@e#N^L^m0$6&X=H`(Kmy_!J;@d;c&N^N9SoTH~Gzzkd7NXwb5{9#@E0{uo&T3N88iupe%NDo7BY6 z7lM#*V*bAd2tLj?!CmsAua_~+xc-8v++w3@3n}##wxwveyLuXS9C<{vB^XO2aXrJ! z4EJ9W89h``ENH`8x2Y{1WQJxNZOAR|s-^V(`22r^*fzObnIU*IU$fd_{Y52hMa;MB z$neLMIr`?c_<6(Dv+UqNESI(!2m5;zkKR%xq>)c;%FY?M27WBYUCPJyc~wcugwP=I zKL3{WoQnS+kIjR+eH(bt=QQI8<3WDLhJ$dqcEA)z#eCGJ1 z_s8mA2+;jOgD0fr8QwdUj7U)wJ8$FK!m~>Q>LsYK$5Q05oA#xeS)`QZ|FCp2fH0r> z7n_1u=mxG|9hWg!1%C7F!Es4Qv}1>vDlQ?p@my%JVB~`U8UDd%i1AG%Foqc{^qePp zn5H&!;&K@TNpg-#^4qY<;|HDfMp(;9-?bTuEBKizeVoDvhKLH}i{Q21MZ9S2rTmS(aG%-pur7(@;1z89G{x*M;t`rl(lg4*FjVxThnXrv0yr{K#z@_c zf(AOCa%C%?jq~l@`BSndi0$R&WO{nLVU!SEhE46y4BO^&$yZGEyF|4m(0KBK9=$m< zC-V!ALN%hdb9~0WsA(W(P5|!k>caa&;^pV4ikB`$8TQ%uQsw!g8x~vfw zWo|SyHfrq0H%IPW|90z$Rdc>eOmgc`${wVW6EB@dxI1wX6I~jc(VZXDm2{FMy2w^; z>A*^eX<%%GUR0fbGEHQ);r<7i_rxES$((eTZ?S)5ORRe+Pw)Qyw=jumd)>n(x=+U@ zO&sQ)R}aDSkxy6HzEEsLVT5J}*W#-q#b2n{p+P6{j>X(hY5TUbLL7=r`SYmY82@D# zd~9QfCN-C}9Iq+13r+8e&=4!p0f7s)D(Q%t&bQ`mdakmLY54N1Y{St24ykk3?=^V? zLHOGoi3ZN;!_MFkVeN*KR#S+Y6K~6+>5c6a#7+C#PAdZ+-HVLe>3e~5&6J+z=Hb)R z(`qY_NyXh!S9@GYZFbsqY6Hu4{E>*|ymxlGtm4to#6~E3=Re?J9KZm{g&5&(XUV~9N*g70SPL_d;v=7Wp2FxY#f+A;3`0*U? z-}aMp)s+ZLXhi#QrRt1khe@bfC@D+RLuu9 zn53^=qsQOR8V;b!#oPX?d+Z zwvrAV_^sJC6RIk)jZd8Hx}RBlS!4OZXf`lL*+Nh8@M2Y1(iAyuymU_xGtV3XEI znzKGJqK(1irVXkiCE>zKB`QDKtu=qMDx7%lv~4?_5c2jOd)-5`H$KVZ3-w>qhFO!2+9WiUJO^JP*KX+8L_sz%I(C&omzbY*H? zeP>V{4GO2l+i7ympCzUWvODJ&0bewv;ZHAK@TJxkESV%ocD`UF?le^AYNFRI5@xq% z<;>itF5cmPJv!3>7H)`?rKXSV|fq|oZk@SA52WM>a`1--)>(kuM7uY+b z_Od5vf48j*FOi1}SzBPhG=R1i{>GGm@eb+zf~te|bBCMVu3$S#tYgJ+aYR+BbrabZp-RA%4Ef4N=YwJquvQeOs9Wb9ZnPchxO2u-tLsi z59BXA%VPNSz|Zi%lt?v;#%NQMa;>-%+h;@DDfj+?hLl}N4i~{M1I;O#yaJd z_ln^E8|u6(XYwlMGf>km9$h~gpSL+JY+BZS zSN}#op*4&X_N5JkFtrReSFX|rgKD;8#_DM^8jga@z2Cft;lPJW=~ay0C8$C;Kfxrn zOauJdkLUa`s-8TGWVs&t*X1Z_)M!k=_q^t6O4+rSuq*`|jaD1>_wg|W-Co!iv!3zM zHr#)aY8?ti7_D;9v?^y&g;L2S`39SV)$#sqL-gleK4Fd^=$@fRd-hXLs;`yWtPPL8^(IgX{RAvd zhsCLg`}n5Nf&7L82fz`*DPJS8psKKRLx(D25bhG8swgYQILjRNpYd!RxnvlMRplvD z?IJXn979d-n{V_|)wFH1z!@!7o$hp15&L+>_d-Po9*uD`45Dh!U3E)6(N zL`*)KMU+K|=rO8|U?H_XZ6r|PE~L_*wqCq^f6=cD=o&p;Ga6#%F4+|L{c0M1?q!v) z%t`-+beYk@GCY$q#g|QdwY(9w2-ZHToeD(PNL`fz!3@t-X-cP=n5O*_SF9928mWVp_?X5XOa>=^!chR!!V}av~}` zQ<6&x5hR_pZ#sGKb`i)?A=Qfy2Gdnp9M0RfK=v33Lt;96cgQ3S#z<4HU2qS>oK!Yh za1tb$<98Y4ed!pWBTb~S-t+?P(Pf&+e92>^K+kp;W?kD%?|9!#md-U{oO7Sm2GrTiBo2=CJrhm)Rr3IZcq4FL0$J_$5D&yUV~KysDr{+UFt1 z{dG$LqkGzvKd#Q|74>aP*%;%Q-fr}y!E7qd$}W1UZVToln2Z>DES5w6J?Z9csJx%f)&@kh#f{s<6}fWb5Q046nmfdUp5_ zCIw#Io!;qNU(p{_2T5ot60(iIDMx>{N7LtK{>K80(_92ecXhm6kp$bTtGOD+-Jl6u z4@~<%L-_a9vm*^W6_vyvOE86QpWu;t8w`rIx@{%zuNH^@>^Xae$yuLW->Nnx^)rOn z?ufO0_5^3+azJK!dmWmh=US7k;=X?Wgj|^J2QE!UcuXsT*J8Zf&geeQK>6{Io%P@+ zsd-ee;a<2lOw(S|*BFigzfN6!4Cafa1q(&~af#;)oDzYUL)em@o*C|4JuV?^TY5x+GF0jkc$@jp5zH3*5wz?7eJl z9twxWc9tTg+pwr4QSqKZVJh-zfk%jSIlDy`wuDt^JocK<(MZBwl6D=naTlU#=?X4q zbKrm@>y$>&hI3~Gr^_o4=?^4wE`CMzcV$?7Jor?ki^>P07c^M`0tz4#<;W_%<3n$R zmpAJ|UK_FE#Z-Eb-trUQU%q`Nx>sDSO^5SelS1kENr4AMQ~{1hl0+PTJo;TR-rs1c z=E;Ri%4DRuO}{%?bk`kut)k8>Zvsgug;(IqtBr&3-!`H}6OitmcCYmPar|N~YK`pb zTFBjG?X!NTq?_@@^@!MRIQcJN+(am*2hWA1s~))JmF1$jfyi%K^%0~tj;bH-j5_c1 zd{&GmCOn*nZj>dAj>NM5!sFCGsL8W^DeZ=j;+^Owf++H!?Yek_Y>N;jO)1jjt!|yp zP14ccw^aKGv|8Vr{c-Bs{c&PDw`)7|^QBc8l0lliPteP8xC#9iQ1;~d;?v| z-pwNy(e)gXKl1m|M1N$osj|{DatA>q-e_wxhE2i!fc&%7s)+1_Rbw zP3RLdgT|Nm(2(&Cy7vaLWUKqRCzf*bB?RINhVrm_%16XizeAIv7{_IkL#X6rlVJpl zbfVOfI28syl3|FYtcbb5jk;Bl4f3LyC0uC-=Nyo8i~~Aa`>8fAoLpZzLPbMvhNtH~ zMXQ|d@sh`3)^ke85L9vLq>&dFr7CTG?&YH4dM%)mn44LT_j(Kgm2)4Pl3)5@*+aLdiXj*J9(<3L24>qKcFmSgEOdt?)XpK|^W z7D4I0Xoiz#fp*R{Ql$Ygbe_?0gsBX};SlEo?4FbXxwjV zm1V%H9F7_|bRj}Tk{<(N&A~d3MnkHqf+3AGuga3LDj5w&IPVw@N8uhOaPm`jFad&b zfIy%l-Q4SZklw@5aOSsM7~f$LUajcFvQ z^?r_>1R$}-;IKGr>$!^^Eenh>4T!JBQ{?#!P_Ty`&)V0u%o7CU_?|)YEIn=;F6&=L(G-rka2V-G*8_%^AH(tCCTK!R zD{PI)FT@1S5I^Uwsfo&2*Np3&YoG|V(%2ed**d%9Su?!`ykM!@1wu=q@v-fkYn~Iu zQB5=+>ugZ{YDn;%-m>snV{LsJ$c0MqY*Lw9=t`LZ^mTrrf^VJ03qNT?D|bSjhqbB6 z#Dq_ESqlLcW{Z|4=qC`c}2Sg%f!>0b}?TGcYuUAA;k`LNr-!w%8w*i_GIi) zFmTf}rIod?&N1lsG1eeuh-t)eM3EN^>g>jq6C?G|wyGw2VML})9DaLG5`2a|H%9AzmKW?_a{%DDGU zmSw#6-h2G;2R{s58t2@bO|a~-t3tbWw71poEF{w<$=@=4v4Fy>2N`XX<>`6esND_psH zg?Hb5m#wYsXX?{Md0` zfBp5xR-KfO`wm4qqAW^o-C8G(W7gKzD2jsBl@*R3KaLQB_uqe?_4V7l_lsXNtwLXV z=|%qMfBSFIQN+g|e?*?=O|a(n#%)$sR(bj5mpOj?7#m-y;ef46C(Eu^3-D~vIm zJ^LbSYik%|D9VyN&u0QhLdrVP$~TeoMn&@vgESxB)$8^6-uJ#oS(SYK>tE-MH{PHu zOVT98IZs)quY}Uo4)4744xeAX%=-H6x^cQ{ntoSR#n$!~qftmr8L#~_!}#tsR+Nx< zYx&_1e!x$E{1g6%Km0?6g8?_LU8fl3oH%}*^Q|`RRtsYcTU%Rr@5qZ0mo9zA+i$;( zr$UI3`tXG>zRK;}*ZJ$e{!e`6EAQ~)i)U%28f<|Ub>!6x1P+Np;ZXu)9h~>Rj?nq} z;E!0~cRHN6WIT$T`dRp<=l8BpIQRqnjsZmdUN>*v;QY5g;nb;9oI0__?#cQv=&a1D!9@L+uC2rol#f|GXF;&T(joaM0vq87p!C8Zj6nE}y zFiydkylb7)D1QJ0UMYLKOr@JTl%2&S1@#Dw% z=YReI8@Jcl+S=sg@#DOB_63ftuJX~xA9M1=39?qo>dGo_zWD~*+jkJs^5x(8Eu1rW zDo#Ilir@X+FLUP1X>3&xNlzLpnlx!2(zvA;NE{MZ6N_I!@VoiR_bTu6yR5{dmSE8r zha!PRH;bA1h&r+!$1y^9&c5+FzyJHcPmvF}^7(m$RJ`@po4oqUE3B*>;q%Wg@yV}$ z&DPcyqtS??N00LQYp-$r+BIH&=_S^VuJVH){xgGqkGJ3c9nPQsj7}%z@BZ$`cyAY+ zbHVix7(s+Obnj|LU`HJy3)g=!V~8o9UliXP|6ZLsefodd(WmxNe2H-%+-WisAO%WE z+G)xw=gt9+?|<)meD>L|@y>Aj_ANT?7O%W=j*mY6n4kRQCoHcl^TjWGk<-te=E{{T zeDC}JgtZkbD@$x{-r>WKenqF<=G?iLxP19@e){7d(c9Vt90FG_lt+q?qL9QfaS|h> zoaFC|gD}DT-^D%*6HcEc0ne>0aq-S3g%Ba2Cnotovm1X{wMi1XZ^wW}c!l=@XAS4h zz08-s_ys<{bcrAS;QOqvUuSds4!wS#H(q~}JRkD&pZ%1LjdgC_yupoYS8>juq~Np9 zK0zu$mL^=ja+&pwo18iG94Akm;733D7cO18h{x5(TG(abr`ce>CRN<0cr zRDV}^^o}o(O`U@mv%D{+k5+0Xp;a`LSWmXlgu)orp-&tnN|XBd{TMAtuiqJG))2bUns4 zLER_aJ1S!_rD;-UL%y3}I2_c5t7U6zlPp^zjuWU1#(IzfDJSXBX_it|BZk8PO2PoG<(!%da49qf^xKCqFtuGF1tI%;qYl<>wROEP5Au&kl z(2>9k%c$swlxP8I8j)o&-aEXnYI`MA=}F;n-Y^{Y5TXV^!`Agv)9*4#OLwwP=k@|I z!`PGbm2pC^pN7ymh)v*WP8OyZal91zVf($sT)CUr6(-R)1Sy3;D$Te+YV4}?&SOki zT&;D;`!}HwWgHif$|FPwk{MH>wW8bYk{1?ZCAJa>BD9P{m6lQ=p{zN!C00au86$+k zKNLO?L1po3%3u_;I=z@zD0d04?7F``7^>dkylvLrS&Orvgs+QuLL_WmG%=HL zi6RQ=#Z+3gYW8XDOz<;_c(Q&68H$L+RCX__R%L3Y^#UP+s_F^3Ui+PY!ZUkMZRYs} zE>S&kaEPf)LVp0`>h7eH_p=ghQeoz2_j-9bQnp6SK&ToD z(}%V2wn3dzBG@Anl}-%?JAtf^d`o!cCof5>Kd4 zcG$pBKDa!z^W7OMeZI(H|6}#uBl5^lENq~D=2*$nI5B(F$hO{ zrH%K&@J3p)j-uPq9PN5et>$D|i53I2813|VGgGodq%}H9QA!|HP~)rtL5!3dty7{X zBhnhFB5)x(y;_x=>#mS)tkRPL2aJl6H0#y|p$VJlEZ$XkU*dgL@0&wwh!af|38F}b zvPGRy*@WT1v%N9Gm7#vS$e|du80E*Q^ctpDkXH#h$|&3oyvu9(scTabjCFYDsj3oW z8Uzpu?_xkunViZN2od4y`fQXzD3AB1231pFE!LLxN#-!d5UU8`CEj?1mq;HH7rjWS zh_Jqcu?f~HlvGrvs@2yCG>$a}d_k-&tu(@Vhfo@+Qj`QtjlhBq?MA z8?va*~bh|?B!G$hYQNa;zGrmRMIDT!o6Wh-=gl6Lns+N&>c zb$yFgD`VxzG0HN>T0xw^@+urzD|qpg3O-k~$J9E*Cq`kZ4FX^giRo6%i5iuVbg93?E) z6gb<%+7aH5rtB((5E0fWlDI=r6tp_a3`Ul%%?e40%?*_?*h*0rg8p`gp_Ak?Cok5J zKEg(V(&Y#eJQ+}7tz|SA;%r4#8JzC~1x17cd+P*cRp5mq(h0^?R8>x^oe-%|vu>=x zdXF_DOf{@e3QtkxNRc7Eq^v5i!PaorBUD7?B$bUQjm8*>wGJs`oU<5fLy4(#D4hfq z&W`Y|L`aQL!P6Hhfv^&971o3C5?z%i@7{lNXqfD9iYO@?ozi&^Hlb3AD2hqrqd31z zRTUtP2i@OnQ;bU5t)occDXVLg#S%&M0zG$!BCl9kJ%WyM?(_}Dt}z%Y1_O=rZIV>e z?jFJQ?w}({XK9J8;W}QdaqQ&l7}4eCt($z|*g1|KeUY0tZ*tbOC8E#xVilWQL@(Nr10XkkI zj@KBBZZI4Ux&5n8Sy_$IQJdwZliav*3unitXF`-k6jgymQTYNHd8A4(PSgsA3%~}9 zFs@IWr5Ib`MFF}M?7%X|I0HzGaVQ_*yuhPyPGD?}zTrZWV>=DZkmm(U-41c2$cNk9 z*}Q|d0xep2pJ1#*_zb+op%5}gdl&8Ez3~UiWARhbx%m)|-=X?YW6A`4p}Z(UbkIjQ zF9UabSsPReh(HR2jIh4K*dS#=W1Pfzg%=9zD=H%px`i>TNO6iA*Kd*+k~3${u(7#8 ze^??!n{Kzm=U3Mm6_RtWpW(u#D~t-yVB>lw7-dmDgUE^tWTI-9V@-^ly7M zuBL2l^*Da~2wQiyNRo=xl{U9;T*o?t6pjVO^=w3VvD7<7FVubL?@7C5oKX{{?th} zZeHQ&kyWZ9q2F8Q$m%NBu7A#pFCIs#DnxXTtn%6U^L+KIU*!6gYX}lHqn!7C_H(}W zwYT~H_kY3{-ufNxtRE%sUFP)ai@f`zpYqK=_@B7&@h4=RC6e}Ye0K3NZ+vlyOBZi* z;?x?)j$3ZuE{Kwh&Qgb^<%Ewv{uxJBUg7BR7y01BkJug+WO2l~SI+V2r@v+}7;$9n zDD8HOTemjwHYL(6HhLA#CY(HemeD9@G|cIC));MXv9;C57|oH@BMi5Dw6YG~JK9-` z!C;6Gl1RtF(Pb@y2wWR$JkTM{R4_Zd#90kW5XEhj5>%DNIf)iiiA_zOh44+HidH(f zA;$%Wwf9JfP<&ohRb$zQV{wWV>axW#BA5^otutsp9kA8fO zVczF=e|LpTpKr1~EP3k-N4RzK5*zC`k-p%aHx(be_a52GaW3Dvz#shKH~HyLOPqjL zUVomepI3bGja7dA{`)+C+OxTFh2GW;&b|QO|L33Zjc*9fzI=oW7q0MI|J@1x!+-b} zPON^3pa1MLUO4kSzP!P|eD5O9t-Z_-|M4?ow~AIdW$!aq(q%4v`VVZq^%iMdaN>B2 z0?ozG-s7uZ{{~VHIdSSFQFIfbDwdX7l*Kk@UO2{;tI%1}EFbA&s%?6M0a@DN_{k%D z{Of|E=(D_Znv*AwapChzEVp7#o<7dce*OVcYu-BcGS{vR8Ck>gYpYbg;^v(m(tDnN z@kKuS^`{IALp$y8%FD0u)1UpEG>$oa<~ct7lJCtQXl4KO+HWrOk zF;b>@FTo0Qlo3T4cumq;BFUD53srd{9R-6nAJ9snoj5LEzJx0`@l}s1H*5@tym;m) z{b9we%@XN#+HNQU54a`6e5;J;#qePa3a~ zrh>fKK#DIA>0@|X0B_LS{yDu~i*5^A?ce6)sTE|l!p%X->XEle(j#nc_lc6L`h5 zlgchaj?l7)aO-G#RK+cv-^No>RVB_=^m}(|lsrXYEXF#NR+Lr6Xf#B{5oJ|`0I)a2 zali+%rbKIrk{+!*St|}%xgwNlx}wBOg>eq+JW>aJ-FXol1|}zMwNX(-zdt06E!Oz} zLMD;`vSuoj6dXCSj8c-K7|?2`wA&fCH#U(FYDOxF1E* z1abTvS{((^p{NwrB{-)kD~FdF6=w(?2i;V)(eV;Or;JLEqlK{vc_HWxE4;`+YFgbC zon$znNwX!SYJ=}0SVH(^%A$i3C$J`@mt^TGkf3BnnLE6d;1t4XBAFq43_itCAXGut za#;G5c8jF#X?HTp(o>a|D9VsB!5YDG_Xt_iCDI*MSB^6pT8xo6r>Sy}EftCkY(_D3 zXptb%*wRvt%HaB~pcr{5HP|+zzNE?{G#!colp{f`THrNRULm|Di6e})6lF+zH_l+a z!PRcryd0q;O_Ih8MtxluJh1s6Q%Wjj2R>`#$&tym0(d6l}E-ILMP-# zV2BV=hC`EA9_vD4mZT1}cnEQ?66q_XE5VfDEYdk78eEKUF&G6_f&*(k);Mq>aw?>T zNMZAW!S;aBpd=r~i&CZl03ZNKL_t&-Yz5A0x}7dUga~)HyF|O)q1{;}&RXa=#n|9x zER3h9Dk@vhUh2^5D1_c*^;kx$l{CRJ>qQ;hQAnX{A2;AFN(cYD6CO{5bqU_5AX*q3 z5yf4c&q3rEH^BP>>qZzi#JT}hwMCM`+OY_wE!M%HtguqylQu-Fl(NOG%@Lb}f?-kO zRYqP4^1>lxf*{6vMP3Rjt0_xCIWl-BF@?pKplynDDW(7|Vl)xLYou3b;`(O|HbVI> z5ld*=M5IU`BV0rzQ6xW0&2eUa`sL8QT?7%1Jkw zanVW**XTUh+L!BPj6sJ8r;M>eW1YmIa3Tudy$U_cghbWP*N8f3>X6=`yg~SYoTj}% zxCms1Ga6G0a1mIA^Rf=wIjpO2l&Hv{q6#5$lq^xoAgGX{AdU-=+f?p4TfGZx_b-wc z*Fg+1ZotOoRc>!yXOM4F=C`rtHk+I0xqS5lB7GBQKBwRR93lF6Il_xT#E1fk3BLbW zQB~XEOVUhY%{Ey};(SSzNV0Z<$5NRbp>jH1!6?5?S@kK+7Ea`dsA5>G6Q!1{Yp|jq zcO`NA1j{F0hSu}gXqA`0@ZaP0DnfVI?Da^yE8O1bv$Zuus)$ixC`(6gFl3Y$rrlbm z997uLpb(g_{BhL<VDGpyL7^ds<6^D!mwt~6>@Q8b?rkgHVf=tdk=kQ3_`(%G@GF4KP-xa?7#f$62Jeh)Djgeo|5>8{k~$ zTwUX_!SDcT&>tbCVtIL)L2o-Ol8!mLvck>l zH>iwZZEcNVKA_*bO{?1?OI!2@ImQXHRtFuoP*Fm6Wr?hnaC752{n0i@kFKF3iPDB+ z$5+s*31mr%-c@%+aeJ$jr@M-xY&Rg10d5rfiERxSF2A!#aU zw^E9tN2KAz@#EaQzRvdcHftv|)>d4I`t@rpue4CnRZL|OevOYlI?tPLo}wzRu(H%4QVHeA z@Y1<8e(}L|P_J?R;wf%zr;NlBzxa8{b0=Tp()nLg6(h3bI2-Fj){duGBQT{x${{yz zuG8wAq$~=ga16G$NTM!Bx<|Nv8w`eMrD?Yl`hyUy3*m!#uh?2){d@l_4*B#msd#Bj4Vmm+}gmo zfI3}O66YgUSJ$Y@ilQ1Z9QHYN@))<**XNj^ZVKUR81vvg9i#t>sjS2r9Cw`eA><4i znP8&VTUVzjdr(TDwZ=M6WeiFyI;}Q?{s3z&NgUJebhxv52Pp+BM_1_$`Us^dDuc6* ztR4CbjJCE>X$vWJ9VYj*vo^v*8l?<+11e)!UhYzqIfLPV<>e(>S&LC_XmwVI(iVe! zMAmK7TIzyy6xEQz3|U%QMr+5?vSwv9=I9a4i4#L!|H4n{b}lpAUZ>k>5l5ah4Y>JA z=A@~`*$hX*s8S3DE2L=~!GP_pbwKR(*ga&pm6$x)@VY6v2p9 zS|GH-n4?s#MCpP!Izg-zTJ;dD6X_A&8b)V_i%fSHSHMc##;(Z|Z<fQDdg;fU$p-agO=KW;WI~kl)^hUIJs!P-PAMejmKRSjU~sO;n;$ zTH-2;!=bbwBu&-@Gm)ZSjZjh(ClRi+6nTk~F;Od}stig$=Tk9BpRUgkSrVFy`acjoIbS_;vcflayP+LimWvXX#kZ#*7;1%SLFFRc~N0( ziS+}VPq3~+$eRc`44)BgoFgRTnHHwdn5sgnc2H$>hLGD-Y+;R~x0NIH8bcS+Sv|@2 zjTW1CwkgUUT6Wpo?&Dd-`3&a;O0D3HrE;38Xe00#qi`<5ng}5@{jGIkp~#&>NQHG3 zRcRRv3Zke@Sq4HhmBv&B&eZAFzRviZ$_$pZTRwCZqDC24Sm(e=l+p+!#^!iDm8pnb zjJ1ZM$V2w33<-zUJDl}MC2&=Rbq?hy%*{RHniGy<4N`bBv_bM>O*EOezK zY*kItorS=;I`Ae#Gmv1M1f$zIhaqH$;yl(^(ryc>bm+LE6iJeh=LI58iQ||gNf?Yq z=qRGqZd3RXS*Jz2-DNl$F&qu)bW&Qalw0fTNUd1zw7IjjMd>`<)fG;hI?6_W8!aN% zj;-Q+MI5D^Jb8px%i*}i>WW}(4PxEJn+!#aiUg68xXNM55s^+Qh7KVdUc^}2B~~kS zOhO@L9K0{yA-u-hKE`Y#bVXrPgl$o}m@HjFqp>z3&J%aIt1^~ae}RK@}gkn$O>EALn>>D z;-of8EjkX#c&f&lS1JUtilVH$;HVnq&ILRp1>Smemhk^G_GV3%W#@U`v!*?qG3TnT z>Z-1ufCd3H0ZuYSQnDSCWl=W@4;T77zSEEJ5AcP;j_?&phZVZuBoPD%5NrV5Ko2!$ zR!(Qw(;9uT_BmM%*%7XYjLNDyHRV}rul0T3`#!G_1?%++Ar;z`_yD8Ct?%vtWu5KAebQG#5yPR0b{HEJ3Bfhm1T_+U%duyC|ZZoRTocWJP2M)RUUvL+;TF zn9U|MZAXfU$#jBWZ*s1gQp{#kZf|c8QgC>{fz<;BYjBJlRx_gSrO zxgCXa)_bJPSA*$v%68kLOo390>2%8V%?hC;v&EdD?J=chvYeu8O?S~#PD+l>jyS)% zASpOFUeNgsjq9nWildV`pFjVUqAIEChrE1o!QsIP+s&4$ELd-^NN(VGvE<8N1&$WS z%*v9JljD&Dkyy+$zx?b|%5uUtKYE*+Rl~i5cNwhV>hdMGH!tu$^5DTk1d+{Vi?^P~ zkKd;4w_IO!h?o}@Wrgb#=m}51Jm>vy+()JvF-+K8&(VcvF+bs}FRn4wF$eRvA>u zq8!(y$`9G3P-=#CVGIWu)d=K4-)vTMeRY%DqgtbL5MDrQ&GKN$)#VjhD-Mqid42Jk z1Wf9Rs;;=YyaoZw<&>uBXuH5-KBMhAthGoXn9moqZA${mszNkPuFR#Ntcty2yPnp} zr&FH2xS*PpES3wNzq~*Q!Qx$@$w6VI%IiVvuSU*-QI9=Zw_+cdUcMCE%mbI>ij8v-!rWg zUw!peR$umO-h2Oy=P!RiAvdi5;CJ}XfBhNldc)iI9x$7>eDcZ9h;iT#|M2^K_2o6* zHT=eRBR~K7r)cvz%fo`-`zOD_U;ou7%omzJ`ol*M1ONDwS6p8{K;#8%NO`Ip2ehgwOP%u~v_k4p3^DTci$XID0pg6=3xf#v^G`*L(C}S(f|hur`WfjJ6R7Okt2R@9-!R5r{$% z1Vowb9+8Alf+WW|vq%Ufcau1@)F`F)*RVYUR4}S4*M`x+kn4*Hwp}9PBl_korsez8<{i5A0ii#mT^(?9IpyWkL~>_r zZ>JRE44n>$J#240{Z`U96^128v$r{0JZ4!xrf*8LJYYIq&~}#X3i{5Gf~IQ~k|m4j zdq^HIDc=Ks#Noj=xp<{`^%4Z9yuMKU@)rZPT~MfRV7DJ&n{UwEyvOyc`@DXBjOzr+ zM`TDy?;to*@PwhIC!FCOVj>W7**d8S!v+0CFOH$J!$?eYQz&S=gfr6BnO-rmN}A%q@lTb%C+!Hz#S;9N@x9pJ`a&#&3J^@L2>aW>j6%d#GwW}4}2 zf+-|PM52tSLX$+mMu!iMm>da@mNCaQ?LyMtq%OyBXW5J4>%ny)#2f}UhQfuEMxRd3 z6pOnA6S*6{z41BOP$9-?s9-cr#JE?ZN-4%cM;zN}VQ;}yT8>?-fROpeyMjtcFonSu zCG~VdRac0jM(Yw&l$b&jZH16JpGYYnQlcs)Qh1U~94w|38v4FtS{syKP&}ajr$lC0bS4z9<(cwZILEDS;`w|%@;A?`@I4e=glagmTU7+N1iXw{+V^nxo;B7?=70w#EP7?hD zX#g=p$iuANQ41vZz`unIXJ{TF;tet-q$u(OPAVMv>n~D73NTth%DsE7E3_5}Evd>} zmq`RkNMf+mWu0ANNsk*KcNArwQK73EsT4xwsjv5z5G;u>S~3GtB|`N1BZ!e#6tl{J zIIagjZnBUaaz5gm$68DDYldNpbJuxT97aWQibU`6&gOqtOj*ygo6e?~ojm|yG*$0X zCu7Y2sH|5Nxv+?15ggOLpib%6v!-@~uaP_^?xxVrMXU{POq_S=C>a5=18jI__ZxDz zpY{{yJ#Zu!QQ4&sNY)Vo#4P_I#r$+Ys8Qx>vX3f1FQ8l&Rb$MG_B3o zzSg2sU>E{16clDo^aUx_)b$Zf(@~Z)jLAivloBZnQb>Bc0bJcLL}0&88ivGPVDr#7SjA&|e$Nf3M(k@#{y z$@g80EX!=IOoEgIUGKTM-4LTBCdFVQF=f7xkCKR{C@X|iV>Da>kv9T+f3+tBO9(w$ zN07Iqbc2pHWtcFDU;`MJP#$Eg#!;+5rZ#a@fwrv$Od`RoP)Y|%0J{?=-pkE zYPwscaXdZZZX6s(0bBkv`>r3`VUZ9#-uXQ3ONkWycrpl7<``s;aa71C_sklFK#d4L zog_Nl{WyiY%}SC48;LF()}t51QAh>}AJTrpZJoo1FfOc=7o*VG1s6cd8e>E@cKA3B zdMuF!AvOph@j-&vQdCo%wRk5WX{0Q%PBJ)wivxpi>AlAZfekG>w7A%zr6o!W(vD_* zm#=p!pp-?bfK(nKJyMO)s`AcQE>fa2B}o{nVvf{P42r6pQkA)zBXCF@Qn>Nqq7fqA zrCpA59#d9yoy9vyDgWQP&Z5hb7<065Bq5B(`^Yd1xeLe}u(0vum$G1acs90^6Ddk! zk|4^_EL0+7g;L|^BXOfJ3)G?}CQm;&;`n|km8JPo34(1%q9lqNY}$hP0^}#uvEo3? zScn%}_4BX2sn7UO7&WxdUe8b0H?Y zclp=H>z4QV4e-u0^!@IIY&RSF-sUe{6sVMmpjs%5$R=@;#0W(pbFWw;FjAtW0%`Jf zYcy*sVe*?SOOS7DfDxlIn=UEJ2|fgl4^MbeJf~@3T35{GGmI%IO2N@lmO{tWAa#w@ zlA>~$K4JY!Hth>8Z#=zyhzn0yZ6wR(6r{!ZmO=#*0ihDQa_EUiR|)4WXp2-9p)DzP zAUl$1kHK*FtpZZENV!7F z5~*$w;x?aLN+T6$BM?R*l|%|fQD|ZWSRi zl#5p`=NKczXjO~j=Xpo(QmGgX%xOF{y^EwsHr3cX$yGbg@GeSpjPw*Sh3B33BxesU@oYIbskwK5!s){m-~Fu#A$81;)>N}V-vx9%387e_tLs@q`d4Eb-6)cvPC+}7CgXiqtDQEWr zAAj$J5MVa%`TlR8P?r_+S&y!s^X=bEEEYYd_g?e(-Ij7vu{%U)ll2r&nlOQjG}GFX>is}$Q!PutpY@Mk$#)+97Vp(*qP zf}zk;V$j%uycviH6kY3aE@Z*prsdVE3+k%m{NjSXx7fiGVvkUcNnKzHMT`Tb2^4C@ zw2YW?FD6Ay72)2T%SQ0*iwlI7|I1jz3d*u%7={sJkzcOjNeL!(P2c4tdMPDF>JiTYbyZUo1*_E>V>C)DoVA1)I9M*|dPm=T z-gDUuFJ?R8asR_{@OpJYOo9849$~#hX~o&;G0s{FQ!tyC9G?^%9wp9B z4No3dOsCH{Ir2omq3;?>Q?OV}sU{8U)fy=(7RwF85E%LyhsQ^R=xDkP+CU6LCTpY; ztygIC3R9L`UIbJ;=4h_yS2qYJ(e)97>``@3l8&KU&~N9|)0b#f&^A+s&{Hp#oL{V& z&F`~aueo=2h#MB9DCyb_!!Tnuo1)bgt*>ytA;m;d1+1NLb#=_kSC44=Lw@*^FX_7@ zj*lO+-fVdK)fdE2uw4y!*D{^d5EFgB!UfN4K4%zOZm!o%%Lzsqu3q0DlVrJEu-U8` ztmXLlh@tQ42TKf|v(pn^zrG;&#C&$hY<9@2SFeytaj;x)b#;}gcq)6+W3VJFMWqOF zAVfDRMJ3J;4DK}vk1?9*w5Kj_I9_ZyozzUUW;vbH4+BaIf>QkS^9!E7>=~LjhGqF^ zvwL@N+`IEp7{fJP__tX$WM)Hlk`&|IF4C zF-&F#Z7f1~rV9z~OVF0(Nu(@ap^6@ihFBw#WMU$A6>u1ov6S;3F|0D1r*zEcCv1m% zRFflaw-sfj5waqY`J~=kN>g)ocAvJnVmhg~zP!y-{g7zdmKbcVt-OaQn9e5P6CuV7 z5GV>l1Roh4gxT=26YLMefOEH4>rpCkd%MZE5SdL+-nkL<1;b#8$?qq_G316xp-(W{ zkdkC*2V8T^)r%GX5VIc1JBLzp5P7}H^q3g4aZ7&<)%ONH;>~>PuwSI&Yc~4*OTL!Q zo<=8{7}Xc)&U>(PUXHH~qf&LRMH&To`Klxk@{VAv^@xKRnLC*eI(m^Md%>QNl1VjV zQctkXGT2C2R4f*USPNw-m`vtKCvkX|2IhxHw8KDEYU;@ZQy6BmDfjL#m`r-=`j+K^ z;_yfzksEv}alR(D3Lml*M5&#WB>|SfwcytHU?H~X zWN|1=6c}`VqopT_Jl9C6B_@RpEh0hijvzL8pC{-cNy%vk2Z5cXz98FW3px`5!r4x2q`!^KE(AZdkJLC;o%|AU*6(FU_PA@ykx!F zQqQU^g!3WS0#YJWt^tJ-m@?ZhO{w=P0*T1nDWRCnW=JV>Ckllzn#rVMb#t3l#zh{G zIiH1bg(>J`pPM?dBF2)g?WpTH^VxlFhAV;?GPO=6l2n+wqSAulc10-#g)-=gpev@+Go>!GGbv0rqc;po2(+NTNcX$4vy||eSJyqA_vO@W{V}SU*Aww zGfZLVZK5bN%i}qRr>DGl`HJOY#_`bsP1|tq-WiV`&XBqTVOcCH=5s?)97DWj*apf< zF`HCOCnZVT(l%S_NkuiuT6tLD?Sv2%K4y$y3YmVEuUsBu@|z=*LB$G{YD_9nN#ljV zih(Evy=zfw&ZM|c5&e!!m@np3b(FH>bMhWVwVjHrzxF`)pkpotQ5P0wDx|X8Q zR8>h|X`G7`WdS14v^}O!D3xbDAtWM-!ql0oN>-tUkU$u8SrCIDT1!v&*03ZNKL_t(*tZTS`{~_S%Ru?p(=kYtow0+Ojl|#iqWdhSeWD|)gIKRE-oe$3l zog-L-k0oVQvOGNIi!W~w=8)sJp78SghM}J#MMMZk-!ADoM^zc3n=zYCk+Q@Ej}Q%2 zRWO?#@a41DczeQT6-C!F&z@463O5Y2O~-uZ zFgoK9x7#f#M(kiwQE_;1fD{5d3@jHlo6VZd>NPP;I6Hoic7020JA@FNoSyO7XTL-# z&B^gG>rF>W11Sxow?Ly*8m~b+T1nb7j07Re&ZW=cD$-~0mJkT9nAS5kgT?h-7UHGc z43bLhv_lc8B=h;4)$J`xOAZeYxP1K@cG{t;1>w!?%riOMOhFx>r7$OxrMe~Me4d_v7Gbbz+rC^Vb(Dqq8tr0H5#O^>N6rn5P#^@`aVmJn`hpkFo-qt7-v96|o;~{kT5Y+x{IB@IU;P8!dd8#*4zyBTn@~?i(Vo~r%e|Qgp;LFbf zo6VYk{U;B3etyM|fAkU+ERP>A7@E)d>=#)(^cO$+Oa7;S`^Q}0UUL325Qh&qKKY!F zzV#jckAMFU6y;kydh(Dz`|}?Y;xX6PulW7n|Cpy=JtIWNlP3@Ovp@Zh%qJ7hP6F?} z_lUpx>mPG^?}&f(C*R_y|IqRB#Rd1?{)ErJe9l)Fp7y%pkN%rK;fr5=&StY=Hd*q? zPk+v4yW#5mCExkZ$6P#pikZ$hJ-v@og6s1Omh&ZAEBdxa6ytR`1iZDBg`iUzQs$k- zxvXThwqrW2Su85NZz+nJ#j@npc~4^HExqxs6Qosj?Py)S!t7k8npV4e1{q_|6jBX7goMMEcSyhxpVp5%=#H{2+bMdr+_;v-CPnvqVET+Yglh?xw&{vsUINIgnrW#oq%9SvCNnfUt+`r zE#`P9aZVB<^c@&=N?A^rO%F+NLhuDf&55)&$Mi--~xj!-IPz%K{r7Mk6wj0u#Tgl$GJRk$v<_eJRf`vVbp}^L>c9-Vq979>~QkS)y$_Qj#d0*_Kj{6H}?FswqV=L7OtiJ^9>e z>bn+GcvRug#$=(KZYYWw)(#X!m0eI$p`^qVCBaQ0RoKCkM3qU^=PA6osL#4BijK7+D_78TuQ9 zY=~(~h*i!UNY{iENnsc_qtBf#k%+;OL`S3}q%ewsyAicAj0K@3#35e;2pA*LCL*y2 znFBzCut;fL64wEiUA>p@x2}GjWOnEg(Q$k zP!`$A7Xlzn>J)II_%u!n-5WXl%PL59*`i}K_#lhhLAAkH2AAI-$=NA_=+m5#%9r5lr1_X|_ zfseoU9#0-eg#SnE?T?v=Er#4;4p+n(~%pA6_x);SKspHo-nsD${$^UE7=>zabaRS5CO(aliV(sG=@sLXCO6zu z$|5!)^5igvfbY7IYbx^~PfC=^ic76EgBd|zDKGFOB2|?ES*XZ-wqQ1!v)VQkWr37x zjEj<(LV(=Rbk8|E$@NLoJR_vnw8LktHm`Yc4!@({B8lfbd;SaVKbYa;C8q3vErY$J zoDB5-3iNFTdikEDR`{T>p`uVNNj4-l2m=Dw@7mZ@|?c! zQ2Ls#`y5kT5kg1PmI(C%BQ%G4<$u5%ohSJ6;dh+l>-yY z#W4(FI4i4uMP|3f<@vUVtie2y?mvh&6mjnaub?a=5U-A$V9 zV39%+d|(*teuE9Y#k+_?WFvOW5;=*)TaT7HM*|@VekVb`OGH#fMWHL44G2>ZqreW9 zqO7n!pH50Dj4rT2u-&v6Q&E;GXCEvMsU|a)%bLY}$p_!~21Q{BY0EdhrFrzQ;NGd= z_(-rg76d=zYCihzhQl+*TaPqSbtLrz?mv2kDH5{$8H>XSm*J8}?{ysA zD<~{H2?h~72PfB5w7fk8PR?4s_gjY?o^(XvIXdkq#7m08g1X?H4;t#(IVTT3<$J%k z0b#hg>G{pyx3~rz(3MSJjLgdf0emBdgcXScgca+szdoi69lAHC4w(pQiaecF)YdgC3 z3hx7Ny>*Y21R-Xz=Bt+%41>>nTNlPFuEe>>r=R|k7y=4|LRr!;oKV9)MUq#*=WtM%QW?9B|8 zIC6-_P0+Rd9?I2s{l54~BsQyc-UuYtt6Sm-=t?oswcV&b74-eUFxYIc?j0dE`@eO) zZt_G?D(v9!KB1(}6bcs*Da)$`f}!sbV~Ah$0c1&0O){f@7%0mUI|MejYmCxVg&@T| zY${YiOaf~o^W|YK_>^L~JU|=8;lY&Cdo$j7|CqY8oE{H+^sRdwE(}$XQ7`}OkAIt@ zh*Xnnynl$2hm@0-wA(pH2j8S=8rosY_y6g)v35nFBL>fV@6TCIzk`x%(3;u&41z|u zmq<6^cYpUCQgy`d{qaMbUK66{!w(;0yOOf}7BK|=&HwlvT)JVlyyd}@CluuwQa)im zSA74sb7$`GXv)XmKjLV4z^t%L3(X(=(LX1ogenGp=XZXC>x(m9Jb#b2f5Z>}{uy1r zWVt+HI+^hKm%pTK8>+g-dy7zltLtlKi%B-jj}Wxw@c~N7ELEusWR&>evQtp&tOc_k z>mpL-HIxa1iKgp`m#^~^-$z!f^(bM#BO%6-bkYwtOV@)ViIg9WLPMPAR9)$Sh)fka z%-BeakyXCvr$iLs1Xy9Pu_iJ_-%%vQz8$$o!hKCU6!%xA!MZ&u&N;se)yz-vVb~j9 zhCX`+YULm+fvRF$f1#2ATpSx1!6Qs|s7jF1 za&Ww6dH4!5LWH#vNaYFYin6LO`WjVSGB3e}0SZv`6lsgDJ4!9kC`5$hb2O?nX7u<3 zM7l)_j|d7>!lxeR8zP!ShbkpWmDyD%S4ee1l!?i*CioZlFwpjiYNin=T+mGC2BgA< zo+6aMIuF(8sjD-T+ESNKxVSh6EQN8T*m84y!Fqj@L5DF=mI5Pl5{(dn>8#H9#n3UC z);Mnw3ChZh^7W9V5u>e4N{!S$x7h74))=0qZE2f!zn)@j*i{9iUVki_#pp}O8+?C3 zPjYl1rVJcTnv^nZ*fPf_eJ2f)f`}q8&A?_UcJ@j})P)(ZCFyJVu_5^XqSYmm*rOA7 zVyC^8ZcJgnW0T&2jf520=)x|VHOKMnm@-0UQJfleK+d^Qi=JIY&gKr5mYFx|?0`g) zVxrk*RcBdLXsNRsF2sGCR{&L6Xla;ED-M=NY`P|UPPNY6i3BId3+8i0p(B$D zCY2w90R89-2!s?!ArQrY4;CpbbgS$u@&hpz#01I+3SCjEu>|*9f|R6GfE@5+(6|&9 zmmuW^1$94s+ykz#^Yk`UzRM5~BCP!$DgG||}JqLL*f z2Vsl#hEg4&#R_8L_;5l$B$T#j-E(kQf~@dKvE9DT0zn^;!lU(wQArUYeD0zNfe#K- z6uBGa+~_uwR3kX8sw-0TBTP5fb14R*Py6Uy7hPT};tihFm|q=7U~(FZ`4laP8-%PN z%}CLZgaff5(IZE*{+kJNF=`OS7~y(nh8%H=zm`s!@=z?h`sH5Wwkvwm*s(NPj~T-G zFO(v;Pa)@W?dA$aQ4m6A-V348O5w+LTE0u>lVH~>i#r68%rc2#7$9XYvG)Pz99rkz zbl3F^!@zv8V6j+mdvi(Obu1QhN@Hl6j_G2SnW{cen1Yj|6HbnfahD!b)EpfiFbo5; z$%4mkALhV4I*yhF2a5v;AJeR6NGwVv%Cg8OKrwPz(U`&!qsNBG5XUz;C1lJp5F-ME zyCFu2Of!P(2m-XuCzX+8w;fZWAJ7GKgCL0(=Wi(LZ&GMM+y9cp3T;MrRx%`;fo56_ z1R?KCDk>te|sX1#5XivWCm622*QRn+SO7Ny7rg{NRkvN+wfFyB!F& z7(>8C*6Xy25ES@?(UQ~CL)ykuPfB76OeS--ZI3aEYEm*^&hfSPV)UeOp=+gboQ@P!b(Qb- zAuyXw==&D$2ZT&ibw#u7@?=`&ez>(3r8RY3u^Eraot4g7hfWj~Lef654;NW1!Pk!{A?RL%S z@gsiqiwY?$i^GD_Sd6@-xBtLf4=P@te@;xpZ=fx5C7(0@YUx(=G})Uxb8VuSC{=NMD)&f`b?;uoI~qh&hFMg7Hv zV>+8NnFwCJdP$6MxLAyy@c~5O=y=NY&CNJ5PIpP)%Yy|&Z)w{eAq0m9OD-=ji4i7~ zI`e;0LJCP$SFAUiabPI(6F)_a)|kT3v^^jwi-H*PWY8Fmb7If(FH1w$b>LEN$rU9j zWt8@0GNEa@>@QLhV-#K6p;SRp6l|KDpi`J^1|O^?#5^`%t#5I5;NW1vy4$kZw3s4~ z-*0Yih|XcOVtsYZ&3eP~Xv$C|p1*vGYa7x~&<}|aERP-?VuuyY>YB|)@$GMaz*k>p zBm0B59`O0Ezc!3Q7m!yg6i-M`0TG3ATTKc{c68MY7k z>T}KNx@1~E=Gm_*HXBD(N%TkG;sOZh59Tyo!}ax=)PIwo|M)p4^KbFsq2%&~) z@Mtl{=(o1Ij=ZH%BrRxd^YLJ#AI5tTHlUy zg7MlDLZmDUyw9pl5d}q2j0PIe+Ki5~fDk5kQ%E^9A$rQn;G9Pro$-9*wQ3kVVHZ{% zY*vMiv*evZbWf8QuUnAK{aKWeuR@uSx6_3{ikU7ZMhJlS7Lp$+WV>+etTBqwlj0rc zC_{%c6IG-f-DISoRDz)M#`VtQ`Tzlj))7L1(KUi4Ac7|1zI0sic_Ra40a%Lf)KZC+9?M|AF(|61}A3@=dL+C z{D``G&V2ra)zwoD7AH7&fl&r6Pmvs>FoAK4HBm%baPY?qFRh?ZP?a=n4~G zbB67Lym!U9QtA%GmF`$bQs(PW2tGr%B>VU%t+FgT_>ADli$0E1>M-IYvmnoVn>YC0 z&yYDG$$66Z1ZRnThZc!KN;ZRqkc+mq=`;B*g}ixVwwQ*Pr6Sk27hGLkVC_KH-r#&i z*EMuq%g}dtSF>JkxVgF}MGX|hB=Z{_CC&+Y*RyE?>&D`{HC>EcU2Pe9K|ds{E!Z{z z?=}4(ur}X=(^!uPQBs--Bm>c4dxfAzsR>#YfX3N~>jOhO(6R8>U`acn${n_yh5 zSW8Mdf>w%M8zoQtQ;Kx`fO8IKhp`(8G33mA!7?2_>CsRrUFKC;AuCYjp9LOCF zF=}Fz1Q!V|VqKnhOs6%Mp59c zKw!|S%pbZ$sDdO^PIy-ZLX}zhOCkwDK*vxk|^nWPYjBbBwaUTVPeX(@XcnM zqf(Kikk^9DkM%6EuWQP($X&kRGit|2n(Y?GMXaUFU$dA{BdB3Mogv48tG71Kf_BK~ zeP+fR4{*L79_hRvH_q6i-F+y{aQ@l;MM z54qDcE=V7I?jehOEXA0{Y}pK7;*I}I9DDdXmFZ5$J!YNvJ-Iq`gyT1cfay1*C>SiEmp9@G?tXWLvNlm{%5%=TB1$BPJ=W!v`o6y==4eyoCZy<) zBA?nj413-LZPtE?Yy~AIQpg~<{QL7vNFw$p{7ziAyG_V3ekmoegQe~IF-Cx|Np$l2 zz1K3ZTppmbzMB~DUfMNXHm{HOaUTLwh@1)){GNK2Qs%+$v_2{AK6VmW_EL*9UQL7$ z8Idt62*XZ+8X0kncNmuaKuzT9QW!CNa@+)VM6>{7+bbcJB8_caA$Kj^yAP%E)H#2y zM$Nmxlx0R5CP7iu2qbk~6MSUbC}wkm^)==BK=d8+MMqh!5Vqmy=q;|U8=7{FHglx9 zK&dOHvlhe^F--smhkBZcyfm>AXkjYjn}z!U|o1 zFo~oCUO1w3SU08j3zE1;;)uu*A)Z63kkXJMXj3CaL6QbzN|fxzKE0qUCMabPG4A0D zl7!SIiyC9dv!8Kj>iU7AG)R$W4Pu-Dg^-YBJdbyQFsfATFpxqVPn)b1*eRg1;yGX8 z+ioDS%bQDk@RvX`URK8VuQaNkxuZ?&zHhqjZa5JWtJ~GyX1Q9e_OyqX5^dA%2^2B1 z=g|b8aKhb}*f{-3tq?8nwDJ@fjl;hXlir`R!^G3T+IRau2y<(51&ZFNJ778i|L zfVf0L-0@c+{tqre%^m7ChDHnmY}&Z7%VlR)R^@c^Ofl}*(>JY&i?#NS$TBH~@(dBN zBjT*JzIVOv^ZXuY+n%nEo4~p>jZPO~=RGcB-f#ho-OI9L`gjOk9H7~NZ-=Nv3?va( z>{v-95mH5SPl#<`Qd~Ik1ap^(Jc?(7#PUy+vyS<@iH{>S&r-bmL{uc=+Uq zGJC~GpB&Q2B;}#UtZpq(=}B2pl9eE zFJHXIm{?AJ`Q_Jit)Z?Y)>&RWf6nT5jZ!(+SGTlHPv7@snT}klB(Qw`-79vx7Oiqt zx9j8`h);%R-#(-73?eC6uWy!E=MaNQ-OCgKyvP59LsVphe+5`BH#AKjOVkj!xw*w! zhsf1`8GM@Z?#qk2?ogG)fl~#faT*i)Z)>@<#1B3WP001BW zNklAPSBeRIR4Trso_LXJ^I#dNCKuAb9(mg#7W>$g<3Wp%5#x_r##>UVg3GvdWX z&sX0RYsH3UzQmAJvMU2V}4&dwfib#=k| zc8d>z>2ylp^~ncNFe)o#o^g4#VltkwyuOL+Oew0W09=|ktz#LS6b3d0yGRk4tx`yw z8?fGhh=zV^ZH#PHQSKcA>4NN#Dg|~#N6H;?<$j$X_QjO=zQH9mu+j#&pJSH(-jh-z z;}9)z-@kWj4ezeekb_H*8%GD%V8Oy|=m^vVRY`2z1eFJ4|E z&O07FEI194vf7fD1NHm`y8N1~%;}7$96M%3fzlVzI1@a<8J3$p0^DIbpK4?i&EP_k z7c=USMk$N+ZE}bmaq;pwMLuG6yCt7Y*>yW+qZym#1tApZ{0LnHbXlQvM^HCN-J^?& z*6b*CMKNmd?2x6!hc%rm5Us%a8(hfQb)K$SV->8LfXJS*+6u0hn)OzYmk*g|BVIoL z7Uv8{N2jA9!u8E}v~5E@%BV+UuCA_;Y@ z2b>6K6_o+aCI<5j{XmhIheOvoOQsd0s-kT-^g|cP-6{9ld5_9eoE0QZ+CFZ~d6%%C zmJp)yz@>KTzM&F5>9Lg8|9`Qq`+Q*^{NW<9U%>Y-vEpzO-(OT!{Iz$45Xke0>?2*O z^DJX914U8B$#B*uv_?)|N#9#eADois1?T5iOlLFZ$1}e9=1a0tb96kXs&baA zTdY?M#*mi<)7hA(Zyu2qTk1)}d|q&LvSK_Lqh!1g5}MOYJ5bv)Rc8bR-R!^ z$?feeI@3IS^n_gltJ{i4kKUx&_FP}T=Hz(FVsXmV)hqI>;Ektma&_^F+sm6+nu_LP2b0!lbQikAVw8{| zaaC2Nj^zCYOGv?eiox{J=cv?gT#Qo;tCE5&&l!gJ7*R?`LrOm+^<~1W5GQxW#5Rpe;SP?^RP7<$WQw`JEgF_evf)QTVi*2Q#^(YR#W+@Lba(PGZUJvQB^*xWqXVjCDuHVuR9YPA6Rdm}YC{ZxV3+Bgj@=T(XAuHCre*J=6 zk9qtsr|CP!)l<5`a&>b~Fg?a>sAnT20b>Het(Y$?o#|PQ`Z3aum{ePeqN3S3RQ?8&`GnQhFm&T6D(qMEHp*R;)+qfDoo6UocfQ)vCKpS%A#O8ow8l;FwQd`*PNa{lNBQ@B&g=8n1n=m(j?rj@ z4-x0HpDV>RBCz<>HjfLucMc)p^z4MI%d6yBiS7Skh+@L|e9r6hbEJ&k2fZ(YA_hfc z+Lj<=YK=7mJ_L%QpsdQMFcnc+(d>4#ZBJE|2+?CwtzMQTZQBw;q)W(tILrsivbazF zrYK@(K&DKz;NxR1OJ?uh*w}J4J>J>)NZYq^t>NUon}KWVzz}`hsoS^Z3adT%3Q$#rbo@C!g}&vv0V%x#Z9O z^^%8AYA&z-lDgXPv!8y*=b!zbxPHTIJYzbkxw(0T5Cb26bjDX-K0}EaAAeHv&DY;B z8NZ9jJP#kt`P;ww3#wA_+rRw-l<>U%?wYoJ&L92JyPRL$@V9^a5^0Y(JDuX2SG;(B z%Y(Px=I3Aif`9Z+eutZ7$7=Zvm^YZsH@yGBhy0I!@)t;*^Yo2(`PYB`bF7)tcU#_h z=P9>W7Gnk$Cv$%J+5gM5uBnPOi{patp8uNhY|8Kd;ZOPev*#?Ye??aPHeY^y!)hnF zzRLOWkN*L`{?!+B{lIU1lJV`guUIZGxH>=Q>C?A)_2MPVWkHs*<8E%2OzIkfqwjih zAsN*pvUP^Fmhoi7&_}p$$Ry)&&1$)#?_#Xf(b1GIzSvThIn&vg=P!mN#kW*d#nAVR zs_1C*OCJZMhq&O_($6v-v-8q$mNY0;T2mGUX4u`4F1!aB4_m#bP>TfQZMq#EAII6L z{i(H%x{Y*UDDsT1i{+8hGVM;0K1Z3%={~kI1K*nl6Yj@xrnv(ty)sRwm5Li9-ceG@ zy?0m}(@T7aNr}cee3D*RALSa(M8k!WA?ijcDtkLdIr0snmpm<%Nw+~=DoK+;)`F5SYMC$@ee=2Y%~7vKO5L?mq_~o z=da#jx0+DrmT$jY(6tYlpY%LA{SnLamaYoq`~gF|V|DcnmluYs4^OzdDR}v9M;1;v znLH*BV}{Lh#PA+p|N1jb_XIx}UO!*bZKf=aJ0{hHFaD8Je7U;Qb;!jC?A$YOrVU;O#6IC)U;=+T^C{QM;^ziav6&-4q3+zmp0Gdn+(x^ zDn&G|t7N#|H>;G?hiUU3xe@&RbQ{twULN=~hrbC9XU(1FCuxL)5YfGsHcv1E!47e% z9O+Ln28clL20^?yS!eJ=hp;i9O-evZ7RN`t`0g9l+lXdIWI%xwH9A{RME&j!Z@cz6?1yg%Bz0A)UBoRZ*4|Lg!>DYv3+cS(8RY1`&NG#mztl3h&w=?2#8O$>ht_q{5q z-d8&L8^l3Q5fY?ff1tWVHVGjdOkVmha!&FC@x4WVH^VaTy>x9){(`xn`NK9`s@aS`8Tj7cHy(r|h9?NKJ(TK>_JaP(jEMl;nA!C~C^;l<9QK;%LEm zJfSFb4BrrzfQ=M3F~p~5NKbhwk(om40>AIfvYDI94;C&K1Dky6PV=yT%LLkZWJY~vB@~r$ji!|KJvCx@HZFU*u6)7Dl zRt56lWjO#IARWH)P+sqe&mmbP?;1Js5H(=-n;^{;Lhwi*+#OndPm>nv-fcPDxx()G zkHubM7u?}}q8B-Q?{wcQQ2E|z?+*gE`x|V(Dfa*QG<^*Iu1)J*{6~#HJmP6D_O09f zlrYLCyt4$qryr&7ODe33rx7Xxp&5E}_`0{79ZlCI;B6#tNR<=FFh(Gipr``9Sz~O& zWSUV|nySpma*xsmtvym&oNsZi#n>H6dUQsVJJ=3mq7%)gusV^VmO$dXBA`L!rv zKW0dgST4PV_;J!FP*qZOx&cAV^zyDl2#XK~DP6+j#Dy5a1QHQ+j2-ncg(kR=elG|v z(Dxm-Z^`nEe!HRV+Q|6~9;I}uAfgI6c4Wk%ve>ISN%?C+L?vgI6^BKBe{mla1VW*d zrpOCMRSa~mM_jPD{Km1*ClDwC32Of`46$B!riYB1_J?dQCIr6Ryxi>(I z5G8St9qe-e2=|^A;`^PZ{U_Sv*!OL%5X7PM+0PpG64}G+ie&9HHqs`9LZmP_B@{wM zkW~!4NKXi4e0(d3q`+Gl0ahVH1cg#1LWKyC3K}VMP=RqhAumd-_8gxa^Wu5Qa@{Z; zXN<}bN@Qpin9e5Txy8C00s+&CEZZb_UGK(u9z-B>IR{<_^?CB z9c5`TL87z+Wc1{@Aul_sk)bF(QaJ=YeZNL3 zOV{0!X@m0vyWJH+?8vlcx9hpNc?qFKChm|FJ%S7+6k2An?WzP?mMB?}>5M#!d1ghC zgI3IEb5vDF+pCn(-q@`vi=3jUc#)kWlw!NxG4#=f*>x6UK&vddaQB#<*pb}B*GPg( zf<#Dx_0SIvDHX;z+NMiNHpSm^&9#GnOO6a}n8Y#JFrWc2gyB`Z1(=qoli*T?}?oa)_JbOsgIU!^uTMRyu z(UQ?V5(XrhQkcGvC69NBRF{z#C7B*2{Zauw!x_-JLMaz*jpQg<;x0KG)^p}jMR}`ajl!Dp(mhtqOTxZOW3XT?QCbMhm zv7oA7F{&?^Oe)Iaee$eeRA%gQiIzE;E||?`Or~RI$0s=N$@PdJpq?*inkEMI$pBfN z$bgcp$WcK?N}nUO+XK!Cl*;e~x-Q-o_G_UZhJzmGrE-`{4pw`igKAGuZ zyKNZ;kCYl~Lo`w+L2B1U{yjn@M0+@VW9#+yAXKu((uM9WxG$yJC?RRKyY!6*+NL46 zh+GLiCF7(Yo|1}Y*F^2OaqKo*kQt-0rpQJ#%?4D)U;<6k#Gy+bm5Nema$R6?v`x=s zJVR&k2R)ulIX!#GbW(AAT=4c=3yQ2~acuaf|KXg|(@z*>B~m*6ga71rP^x3TxW(EB zNI#*T-LTu%ROP4Kt_tiR_}TA&$Y3^9`HEb2>>f?{2mkPARP}4TQ2gV6?{^VqOr|~q zoAdX6{~gqL#vlCq{|r_4Snv7h;~z3KGs?ms)fNBgfBqA^e9h7EU-Hf;M-dY8dFbS-pBPjVDRUw*ETxQwdGDhh-5PW71OyMJH_6-|>vLmb%B6L% z-R>x>Q7mn&#SE5FU1N=Bx7nbjB-fFeZ=xEy|w@vgiWCbW4 zXuB;+d1kY54Ciw_)9E<2JOk)FCzlyPh*Xm7W$HQD7>?5Q13?OckJ_HT8;?TRr%Q)Y%ixLnsJAMkl2B%^IGRENRT4 zREgmn_phws?kQni$}_v`==^3mB!o)RReQKV?_WoxIfYLc#=QeA1X35sr_N4%nwYdv zWg=L_Y=ziaFvgJQF@?TqqI6-LbV%M>B#>t!il&qx)0%ozax_0?JG6x0;#gf)n6*+MABS8$^(pZiDq6>mY~$ou}6&fV~C3 z0ofyTz=azEIZCv6Z(?1nIy?i8fgraaT7=p}Z-J08b;b$S>*kKhBO<^`WgGHJU|h#! zTA|rQ9QlwV8B!a(!48UC&5&Y6yEBYyPp2GO_q6R5c^S~EpbQyJI}lt9Ko`oA=^{2D zd=#ZQXQE`;JF>C{JUWY}9F(G}#{>jL5f#45>PRn4-9G320lDIxy=RI_RlgJ|`Z`Md zt?3}h!+q0xe`taXLu`jbi@@OT{A#I8%3^29hd41l^f|-#a%+-`R2^7C{+^$6e-RPF z-`g78S>1$8^8m=S#LIoP=I(*lJxYpuQ{)uXW=)zE$irPhDUB4Vw=3fS&+fCU@(g36 zpV;*6!PK!G2Au0Di;O&z?6zC-d~`^!&$En^#Sv#GXV|NAvP^I^oiUi6+2n{f-~<^qz9BDi)|(~Pdg}3no9k<&F4=Z1 z(^<{M`AfE&HSN)sW_^Q{Jw+9GH3`(!meHhQJpM6mXvwpjERzJkV|ElxL1i()haE#d zVERPt>$@liRuY0iBN>m5ac+urV|129E^4zux}1~QoXxf;AD!{VvtRP~t*6|sdz`b3 zMdZ${Lf!7sh`rdw*q%xg!9+u4E;bqz@#2yjU&@J zbv@?l`kJoq2qBvH-+lKTCKJtvKX{8#-H_`dw(x^R>zbF}9&>dm`S!c-zMp8nCw$$N zMvxadu8pNiU5{~gb%)IptkXN~hdq?wh7AT1F$ zQCSw4dnW9%s#tG!5vwuMn4w1(8P%wy?HbnCEkc1c1FKckr960eOxrf>b}O8NI*eH^ zmq;m@&u4u5<#S$NteDIv2;cMBtLOCF4fFXCZP(&l&(k-KFy@wKb4{5q`0)K7aDCMy zgynd#;QDgIY#upF$H!Be#?p5d(>qR27D!RD*$App#nr_XUDxvddz#hl3PfN$jX~tk zzWSC@-SV@aJmmU%$I;qtNvDR}FxGrsuSC7=HIxA-?df5qv80;J$( zdCU9no$)9C!(Z};fA~X=pT6Yz^NxS((_{Xd|N39>@W1$7zW$}<2OrM4dj1tJp1)+A z&-kDJ_*;JP(OYEWZ@4)BhO;*;KmV)$mE*G+ZT}^+;}3DZPORm|of zM3)XY&!b0YyncCslAe>(1^#b(jE#`4$#l$MTDF@Vr;CcwD36U0;i<gHi@gPEJ|gu5do!`yqCmx*Z}Brgb~S)OB$;AIUO}QV~t=%AE0dgp`7z6O4+Aoo%z71Qn}X#H z^!<+U=n2ak&30YUG?G#NCY$vrwsjHMZpQ8MmcGvjvnjh($@SGGAAj%;#*}0_r_fXS z?TTPKCX@H5ici>XzCy|ei10Bwd_=SP22{t<{EbMa80JjJZ*hEd%6i?Sxj}}vQM?EK zZDe?X3@y2S2mA?2ynzhQ5N^S=dXq~r@aX6x#@RElb2h6BHtQF(%>p4>Mk9yP4OwRK zE`WClwHOD0QYw_(C)>vuB_RR~P=nt{G+aYIXRHX>J4oc2o{PwgNDHc>l# z26 z|Gi^={?{*2@|fo@zWI%E=rF;RcLWM~H#{?gxtr>SJu@hL-;I{c3QDVp#YhU#JtL+l za=I?{ex;-+N{q3G)J(1Krq%M^Q)52@kA{1TG2+mX@-7WRVm~SJhEjd#y+6G6{`ZIB z1|Ga6SVyo9oW~6VwrNl@pd@r%gR^70cE@hl(6@rYcC`JDp<823N7wGS-fkmiCV0B8 zXL)_i(QJyd6+_qJ+yLG(o7SvX*HJv^JnP+-*{o)}-7+4>cv+>UbiJe)6yE13F~;;3 zC)WrO%{o!^=+G)Iym;4&D4NJ46*wnxCPRu6tw%^v;B7`GCJ0}k86!dot|SP9_Z?CU z2nLjN=**+Fpcy=Yh&@EadfV6`YOs9lzI0uiBpRAs(_oCFDEG*fEqPvGj8Bb+NCr_# zMZ;4Fv6G}!#QN-W>a3v~;v8r&1A{dT))I4BG$xsEgp5#UPh^<};rQ&AUr-gA|LIR& zaDMTMZubQreDoHZ&4%6XbH??Ici#PoZZLn>PjJu&-TmUgB8q+gxQKj+N#y%e`mk&6 zeY^`E5!7A2M?#zPq7m zU$dBbihPQ980m5f*Qa_^#a^{_(PW=G2Qec|e~)dn@1E>G@4@yd!hw9Gq$JN`n!GVB z#fYmpE@g2C}k1XiZj@WJOM176hqqLgC2qLJ_1Ug!onz zHBu@vUBpmqFUX4$rFG>0NX2L}O}Z@0Xf%o@dKtSflgT(joke8-?1x;=1~%IUvJ4?r zTyG(kyRp21yeJPF+1Xeoc^{IJG$z=X)Ox=kE#{m{WmP!jZ|`&Mtn&=k()AsKwf9=2 zf9JoubU~lALoo_9d=K0B8yS3uu2DSE#rK{Po;YAr`;9>OKJtA(uoHKJy4Wg>S`lj_ zxq4p$#e0Or4E8WicVwUyK`R6$L1}{0_^9i^gn-uyE5O7)8aj`$upz|0c0e#~SWY zzx+Y>fA_KXkcvVbDAz(n^Zk$lKlb4b5uBB}MF+~YOysu6Im$A9m>X!VAM^$ju%NZB%(TYmd@a@uyww%stDzvhA6k=HPqT(LM?qO0%7 z%2!MmQ|6hYtOF;f4ex!d8PBg#mEo;-M%2@R-~M~=l9yW^KGqbY9g|XV{6Hd#hH7fj z<$&9buwjnpDY`tP8%m6sVuqZ)ces$zb%H=-54EkqS&6q6?_jmw;ZaB_Sgki0=g=Wu zbeHQjK?%I{G(*dByQ1?wnbU|gly%P2G#x{d#k5Tq+suO@_^4zJK5h;q*dc0xL=f1) z#7Hm#?XHXO;{zf@#C!-15Ln&5rtLa>Fkmxom$y;+U1a}NxU2u~;92_M4& z!`iV}oFH_dEHla?!x+P-Kl%~lNsZ1r>Z!%KOX~40Ci}nm;G>$&@`g-HX5$Il)h#EB zlCItI;Pe5j<#oK^2N4;y0NgZWyC=&ZO`x&%a<) z2*#zN?`}C-D6TI9%bTa1uYbt%%baan@Y!dAuFu&uOPsf?HW}89Da#FIQS$obilXX? zjI9al%{f`FQCWevo=H99`Lk!_c~0AQ%;!f8*3vW$lK6ApwW+IUHQsv4B4bilhrmcB zWfav}N8h!)`Q{s3oL{D1e;~^WjERQ(vaHzcniTFX$@7e^GmJ(RS!P*pRyZ4|suE+O zd_79kWmE}#PX{gT(rKdXl%yUF_dWY*vG0@UIq1gs3Q=PW!(h?Lk~vtH9!<%}AY*`& z6yhMWI9z|dOZS6FB9=;`vJC4igB?(rq&FtrPa-tfSc_B|mo{adNu(;0wrLW6WZTC~gsL7fnN2_iid^yV!6`RaOP)QuM56~*%jGSj zI#v#C>p*JSexL#22_E*_Zn+MEYBY*c5FZXOH-tcjxN)uZY&LD083hL8B5^Jy4P9R? zIV7zHFvEb-3TFe&t~nGT&bin*3^6Fu8gqyZ?)#)xxF@v`LZa`c#CKQgxCs4SH7}BG zKk0W4m&$Z+kRrN~_K`~agc&8}y~}fqSn?ty+oeoioJ0-7rXcY|xbsm7I2wS>Ux4wl9#Vufry~4qAb|9 zE3A(I*SsjHsv}Mx)Ql&A$x+W_l5u*rV)}T>c($g>OC&x%a$Qa^2^Q-Ils1PK#CBh=`P8;bxYuyq72|QUMSjrAS)CoiN_&SOQs}2^tiC4A0m}6 zbOYXbx}m46BzViHk~F)X*+^lEShKHompIoET1PRS(K`q_XWN3K1gYg=% z&v1^41d(Z+OWiZ%z09&?t=xl&?rfDIl{*PyluD61@NbM~68GYq(tDF-ns#6M9Ap-I zJa;tG3-9qUL@c$rT;j;b$6iquk)0#sG*AkS)S5Cc4yiVw50q8GWI84rNgh0WLSEE# zZIXWrPuuNy{ra5a<70#joS(lUFA9!NPLNV^v3$+Z(JW;fJLZcCPo7q(FWob$OR}uN z*^JHF(TM?pjR8X-1#FAz+Sp+W|M z5E+Cz%29?Ha!{Di;DyBE6O=ZoGewRMJ$YF$3@ufav)guz>j`aJQ&*1(wxq5Urr(n5 ziq5>Co(ptVQ`dpzjUl&|(O6N975QYs&GkUYCFRIbRmY5~F=eJ%-!51z9&mfRAH0hX077aLgN<)t#ySVdI z%BRh;3@M|uLTiC2G@Eq+6?TFCs?VdytaxxT2~GHk&mbj}n5s$WU3v%a<=$9G}p(4Wm)Xdb{P>*WXfB6SliG z(<6!TFSvMp!`p8wUR_>ue0qlIZYXj|ktx>8mzpR8bZso6RjE7)}-gMX9;I zc}7*iqlZ)4%_W3a4E-&OqZ4j#0^9Wp88r3SaJ*1lT&$UmHD7#r!Q;1{aJ${H+-}K7 zCC+)?fB$X1{Q7Hzev`VMaeaA1S=MYfYv!{v`hLpLNs4U5cDrI)P7uzq+SI7rk(W7- zpB(Y)FJ7V45m&ccUYu_kO(kD{{gSiO$Gm?15`2ZXBQ9RuFbq3>_4%(UN0Sua+oSY0 zp5{f(`RhwO5x2Qs-NtmGyf}1?y0*c(Xnx=4Q21e>Ny(y7{TU?@>~@DCY*m(#CXt4& z)_b&!7EXU~M21*`ngIb!CX;wiFj1~kRTbOqHfi9pWFU(Tm%}EIQbzn?Zz3fu1*yeW zltOErhD$bnk!ChB)L3KLOKq)W{Bt<%k!L~jF;{_*OXPpcDId& z_DO|oJEU=Ft>}lCC!jM;UDs?kG4r_XTE^os!yr=#LyUYqIuZ0k%eb!TjAOG|k>^J= z?Ut@@5$sdfC0~90HAlzCDS*VVYj(VP`I5!)n{1mE?|!ggy?xI5_6vsY3IFoHf5A_G z_Yb(fFg$*AOy9Nq+5hnu{5${Xr<}i5yz%r+My26bzlxfdPk!h*dpPimzx|S@PZx+! zOU_>|DKo{_U*7WZ`=@;UWng(ZaD9EnyYC(G(Z?l!{nwYg^H$D(```VNfA$}J!m7>r z{EJIYA1?^OF|8l)um0s_F5503cjzk12<{oY$_w}Fe-8$NjdP5$_g z{{_GQv!AlQZWvEL;(FZ>l;>x^`$PWX|M?}8`h5(B^Q&7%bNK6D{F+ZcbzEOwk!Mrt zV#^nw{|%2HKVW&Y;>nv8eK)Y#?s$?Hi7r^NyuGEK#6#-#=7!_N>>!ix`;Mk!d2)4?p7}thGMi_??Rq z|L92T zT;uJS;7SxbL^vb36GV835-pMqxJNkG&^HT)?gVE~al;AD9Ak$g2oK2BTlfKjZP9#$ zH-C%m-T^;DiUQc+yhX_O@u4U14rRVUiUDtPhQ?xtfHxr1T!uhG=Gb&%TQ-|pn#FO1 z9EdDU=LObVY~QC;p@>=+A~ro@`};0gX74+%s*?3O&Xhww4Q29Y7<{WQXXl5D&rN?LE25J{owRF&34>2N`}sx&$}?c4N4TN{jnm zQccRuiw(-VT(iASOdt*8l$jd_+b3Xm4g|V@mGq;b2N`>TYQU1LHn#`%d&l2RTaPd4v#b0D*V3 z?V-Hi=*~;H;m(?r4_a+SD4(tmo^d1N!OpoB7prqff00}YHp)oXeWxfS8lF1$8q-*| zVpnRNz$!}9Ovo>(+*xIzOPWlpt~7*ZF2MKIdxWcKT{6qb@o+lS*XW)CXx0<=x50O< zc!X%F;xjdVR}Bg$vxlTKgt`P#$*&0w4d50P%E}Xq!FPOejtcBVy)C>7t;p14S_0fI zTIYakL6%}-?_|Wp{^1SaL#j`lpmc`_ahHLL1YJCaD;D{V@tQ{(de)%7As5QH4X*Pn-Bb@;&F3iLozKjY zxXzHy26Js4mT99aDvDmD<0vILi>^zRFp#!{5Qopf}i`D=DBr ztiqZ0GbFW#eg`zHT|GR1y~+Ii3AX~9Xnb2s}zn^xrXRoyuM zgEmgmJ$2LAn30r-2~l0$u|+?r0~G$b;HwI{2Ibh?cZ_f+<`)VchNt)_#U4%7*B@?S zObQ?u=nf7jpAz4AE$uAbFE!nJ}cuWY-w*t{v;D@WbfiENJ$CYC;x|i zwhjsk{}gZM^fw9s9?b4w2WD0#7G_&p=6@gIIKf|Lq7TRbY)WE1NpmyEqz~ zO1PTZIaB?+2ovLfj(2czwE5$Xi7~UOjj1ir)d|qb`X4H#WE9^0bHoz_=9ab&e?|dd z|3^<}OS6B0^&hr9-TC9rzZ(J!|EJvl==~4h|8xd=DJbxX+Z($)nI|JINcp6n&&1x? z(uD8NR~{ZCb|X`Ec91C#i!q49$cPif%fZS9GB)902Xk|<8?kd6|C=ZoJ11wbow4bY zC_p%qB_IdPVq#PeIdAc_}kY+}mB$_g@O;RJ&?xH*kMJY2k7AYNW>6BbTRHa24pmOr9QjQJ$(9c{tD zbXwYi%}tpd?9Bh%cmkYH^qq_#B^%RUUH`PavjIDs0RsdnsoHOnj2b%EH9X@#oIdwD1AW0KkHucnS#k(+>E; zC+27hcD8p^wYRqsq3^w)|~G5zq@)nAu3mVcHKIr*PO!3Q?} z%LON}tEtH!I{{gL-7>ZS+nJjJ(c^Er{-fRUe?tXUUM_Ah2agHJ$e4o%U=t4q2$+0h zkg<_5w;8LM85bA(|3|u$y_vHc*wIwf9KaF43ZUm7tjOQ|nJBvdw8hQB^l26Vz(6eQ zpnn0z{WoCDe>=?l6f^$eu>kY`4- z{vT=pME_UG{|Mjz!u4Oc{znM>k2?RCUH^sae}usQsPli>^?wa6)PHTKOznUw$PL&m z9eCj10voMo4$@jqFfeF1PajyAZ>a=8BeJuMf&}s|JSrv~^DUmdGYkwljEuObs{8z5 zlb(&CvHHMhk9Ws-63dC*FZVg5=Vw?z3aw5;zi>bX= z2Q7@eVhv+EeNPQ-@-8xv=Jx7#kH_^eNg@K5PWgv) z9HqoO|NeaaJ?5=jp37p5ZPWPJ7}%`Ve&u-g>1TF%8TeA?bLVPqPAhc&SSV??a(p9C z%e)>sJUqNmYahmCZ*T9`%U}omO{&?LpL}`7aJp@`fwvrbz0TkbSsDa)54wz=O^l75 zB}Wg>J#NjDq_-G9-W9y*1e60-j0dQcWjKgHp0qVLEsf2w3J3^raD1hH=1f;eqx#PG zJY}Wv@!?J?n%LtQx^r^`b=nEMt!`SHo73{FyO=5!WEB!xURhB(ir{v$Sy&ME+9|GG zzU@=;HL9)6Y`S-QTyN39+hI@t^_(=*?7S04NuE?LnwZxpjpTQPZS(!r!c3_FvRvBq z*|p!}^~vw45#O^&0}HAreQVI2vq{~pTS#g1?V{5NiASADS|)bB`eDJu>}b!?k?lcv zJI>!Y78V=&Yy(=t{BDq8xYB)A1B4&Xg&)_;jY*~m<0s1X{q8Rvp}$+^m-q=Vd?ov953wwK|2!W~|6d@uF6{P@zq8@vA7Gv%Dp?>;TR8@h7( zjGwjK&d)TvKJY)DGyDCLgR{pJIE7J?2+)p~&Dqrad{khiaf{E5`!~3Pk~1Yk-{uNb zdbDja6{&!WX?x*XM19r%8kM{c*J?goH@3wK`vS`nAxIGeTLXz?zBg;pB*l~v?f1W0 zALod=dwQ5#9yT5xe4BXq`BM-(@L#^1i&jhDE&t%{d%KrsaJv>cX5EjVSJn6%)PORJP#mg3i?uWHRs5F0$XT z+>h%^1`nrU!oTlN{L)=!_jh-1)?c>lY9AjQcs=~uX?eUqF*op8r~$mw_d4QqIl3Jf z5T@w7yc${dxWAmi)9xrRRnRMJW}D3TKABa&>U)ybuPo*BVPt(|G1B&^-M86pW|<`R zFIT)oggekLr!sOm8~LJ6ZkL;Kn5^Co7kHOA-scJ5)16X>v8a)t%-0;f(E=!Y8uudR z_u!$_%ZJ}l+{@(BX0LWW_;OY1hV%_KpG}gzhu69F^Se$v@y?U&fT*WbwH?fqVxpr9 zp0>h|cyH|0uJ|_SGVyOdn^!KW^)2yg;36&XIaMpEz?(|^6C21bd$su~8ME}N$KR&q zMx;NlpP8~M%-~A!(n;*dk>1Fmk|JdqQY&HTH96iry>iV{qtK*HzabQUJa%hINlyMi zfH%d-Ct_eNtOKU)&_BHK#UqwsN@hNBW6Q;^7$8L3QeEen95w4~(f z@^Y;o;5x4CAT#q=Oc<$AznWI0b8XEuYsKDVE63 z)dwI&s|yQxdexjSxKjPk$b5tgQ;F0xwf%cGP9=$zxOcK{cSo}+a64IF~Fyt zc-`iCkXGw=cFdgav7JnXnMmq=Dk|6>R1qSq?|s(w)7~tt#`*5*C@1IjgBE@K=~|lG za&lT4XJxdl+~>{Na%0%+eHJx0jyTKs<(lk>six+to5;Sdw>dgG`ayX2?x5wtdR4~k>a+v1w7B^FWk6^}U7d9CYnit~ zg}^dODOQ-Po#0SSetrlb34uU{r+i#p@ndWN4*c3qc}gpeOAD~^3W|!KVK=Q-mX{wQ z$yy#RCX}wPuhYHPt>a~1PodcI&)_kRlNQev=8muSR2LOUt9q%58$RmChuAp>)grk-Y~Z-zy4+ zT|t}5?CgzX^Y49u`oYZ{YVphGcPoz%QyKeT;XPxYC z`I4I=D$DJ6g52nef+Y=PMRaMvA*64-_grzqvcl&8DOo!>V3TIR&C3@Ez0`A;o)oz z_p@}#TpShkIGB`)je_2^5_c`N^Bu)we315 zjYnB1ml@|%WKCCoj~9i$c$CQOeT3S|Df_w~R*v_7F9*(79qhR37M+(!UVaLUK5u9) zapyd&B`s1 z6$Mx-d^;A?{Ay?MS${giAYlFM_xG=fNh*Vd^m>VE$LZMJ$&s!pc`+bea z1Ct8%kGs?|PX=OOV$#ZFU0YC&=BzN4-238TM=p@K>Q($$zc@WgZ>qd$$g%g{ATqdV ze|dPtMY7DPCAKf=>ZNm5)}-#Xg~ei}eFxURQO*CWCQ`o3-#GjD*v~cvGf~QJnS~qD zU*FMi=ae#(knv&0ZLN+=4ly8K`}t%&D6yVT7$=AJuR=NEYbmWN9V*FBzqCk_YT-#} zi!U0~Z+g-PwJ}Q?twHF83b*)ED0#vs&xlZ5pd(_EW zFRLW(3=iC^h0R;9QoQipb;(B6OFIaLpYst8(}w^txVs(v>Kolt6^24GB8BXgJ|*?c1#v z)(t!7DIsnAH8Lv@@93k&R%dy=R~>y8F9}QwgeNEt(yR6(-%!GfQk(Zf(J_6={(%y5 z2Sjk#aFgEAC1Y2Tlk?0yF5$qyW)~7D&o!1PP_HuFd#!U}bZGyh!F0W3smz*Na$w;% zvD9n8uMFCB?}}*r@mPIjsihAyXXeLUeAl(@n#Rbi;;0UnL4LlqEy|sGe#P z<+fYo@xF0L`NjwQWx!I!UOr9=RAWlivB^|0A2BK7#aQt^AA*0AdzSiOM+SlKiMLWk zW?WHAZR=Ir+$aCC|N1g!^GddXzFlTQej1wTfe2xA#^SgZ+@Y5F+%%4Ot^R0jv`Gc{ zKG|fx=XY=ZTR2(`@C^@Im{TzM!Hcg^%xiPR89AxQNlb%5pa8Xf>l=9PjWX>-eu2Nmv=?jrJ^(XC9-Vt&H zfpkW5aaUzNQx60+P$V)e20fmcmuM%W(M+9Ol49`u+9a>LPLO>q*f2-}u`zHZdE;hY zjC8^j@#`BEpapQN(C1r%6|EaWUE$-EWU}gNAzeHxv$(XMv(tUT{sD1_ZW?MB%~8L| z2fG8OS#f^#-?8N)ew8~x$3G2q0N&^&N1<)uNZ zn0yhaMpjgq6J7r_ip*SNNY^etEMNXHD0iYbGNA3Pv0rB0KoSuoFNdbV-Q& z>wO_!I3(XA4m4FQ7FArBwjGssAfW)(;33HssP6N828`j?|{@@xb=s=FjPAcX71DZsMb|$bMf9?oBLK`$8-{o<> zg0#Nave(ip7DpCWPQpo${hNOIw!-Y=LtD$8#py+f-^pI(Ji-cPBtB(;OMizRKwm?z zs5pAOYqWHS;PvvIZK|;!)t?XILcFSpAd78n5<*#i_4PSWgSVgaqP4N0eU=H9OE9WZScwUT|En*V3}#N`2UU&yYCK zkR>$KR9m`5++CfDU;KfSUe3*{e5Yyr7vBO$+s1~OnMTRikyIINTnvsW4h^V7WHa}IP|KD^VMP_? zXoHYWUL|y-!urH3i;MTj=quZ7>iGRf5_jE&)3xp{Vk2DChEg%d!%oFs z-wxiByw@_Y&ux*_(^IF9UqsnWM}+p1bg17h^#4B2)P?#U9X+qHEFxToKG<*#P2IR> zn(HhsT>oC!zA3nbjOE_}tzcP+lC9j-ifE=93iaU)@1Pf4bmd4FOB*0$ZZ*J-hZ zOjdt{;IHWHxNR+`{7DJN+IQE>zAlgN8d4Y6+^VZh_0S6)6gNo8YTMc_lmy3m3q`fw z+mv->@GzcoTb|G0Fv!5a?8TyGykT3kWlobfemQH-od?enHX z2~{lhM{9E{dY?`$c4(093Vv!*S*c%>%$Rcbch5ptCy?80PmirNWPf4Aw}y=s{N)QT zmDXsh3%c2yU4D$qrj>Drr`H6oHL~+z6-iVx-M6HO+A$450>bXhX$|KP&1IM=ErOSI zEzHzMFsx7eXp&HEd^8rs$iYwn8YsdTYxOTKQhk+ia4@}OdvNfp@{1R%wThW(g+z_@ z(V-1KnT3U`%a(Neriq$)z_KYVnu3Djw)}c$aB;CmLU&Jb1OJK$Gn?+EjLz{*lc&^ z#{I^2iYVeaO@gMFQoymR@O2Qx@F*L0={H}|R#5y@RK<=(#))t3@1>J(*5LHw)J6Te z-4<$@3JZfa8(ayjB0)=9<*Gd(m;mX}g?UUChvuznS;X$-=(_zdP zHB;hN-r9tr_Xo5qmWp%u7f9lkLql5}h)Gf)#cGt4X|9?Y<;c!tA!0RiOQ@Tz-FBnk zfSO$lF>T{#>W`!gN=mdKdNnz@Au2w43PtVIU|btfGA#qlsLhI62DYB%Bl=l%tsJN{ z{H(qnI;HF;470Z0(B9jcxe_KFgKM{Su6XVoom$7bLQY1BP>7JNoqAMe1!~djg`r$O z#7ezomuY|*iJY%dUgXiCK}=Q_CN`M4$|X_QafyEg8msx4nyzeJF?|X>Ftj@vJ%Ba97()zx$ry}zMLH59q4IGv_wr-=9Mp~*~sl=i2sZ{kt& z7tl|5VXs{|o4L7(NN05wzd4;*YMVv)qgKCdY|@zfvxK@BvxO&dU@CN8DuR@E3&?!V+dW)<>gql zb*0zBDsX^%F%oY0ROMURhhmterM@}(&=TQ@w-;@pF~_x#W%z#T=-6&Ht1u?o!g_X2 zM+1^l$>OLGCRx052=Vf?qQts9`f+dpG;kvTI@sTV|ZHx)W(%6g zs8dd$#<#1t)^-=D^%T>uAlmuLX=WcAj5!>=^c;v!6Y#5Dxt$S_e_*HwADNtA5BhA3{0Dsehk_PwP8jVwzN<^U`eoc-~eND znIq!2c$BV2m9wU#+q*aO93IEzO4LFF=$lckD9{ag2Aq5}b5I_kAfEKzdtS0l+zF~5 zzIj&>kid?3hCTwph}{xSkf-Mrxp~sCb{jn*wAlw5Eq)nC5Z`KpFBpu4|Lj;yrFhU# zO#dBXo({AhqsVI%EYa}LiMw)DDg0_q5|o3ir$O5f$n z0_{ndK*al|-bXE;mU#1n+G&fs%N5Pv3)3q)EiIQ`_365t+<6j`)x35(iD8tWDz^4w zIm@%!$=Wg^Jp=S=5vz2L=@nS*xU8o6hKNsKY@ur_b8FKRTT^?w3OBqxWB#l2bz6J` zPOoaJqbXmt-`qLSru_K4V|+)#sVE}#ANq@Z9D+8| zJF8qJ5Z0E1^QuH^V1m4ishYm~IB5Kqv1jN_g5!!9+&es1Ze+ftF; zbDV)l62J$Nm!I9v^|^SD@ipm4FK&$sgm z)>lzTpqU-mhBvdTElKD`P1xjWTZ11M@}*5BFM3bVh3S}rAVKhJQ8vA4i=)P3x=97g z{!A|>1=m+7^xasOZ4Y|*O*N5}0bgS^9zySt8*mbFb=3d;aJ9jX7;12NwM|WE`=*4x zw&g}|1l9RoLO*>?GP}vK_F0LNVV6s;%M2&6YgA&^`ZA0!v6Ifql&-{6xmo*l%1qU7 z-2T9zsI;V-XvHdUem6*sI&!e&2efht`cRU*sFTO%`@H&vGiRaR6j?{$;GwL7ICgz4 z#AE(8X@{nZZkPy#A~@F%=<=%mralVdIYPs324ExHjuF&!lUU?uA;&Z3gP@rg&y`WT< z`)%3mV8G;xHru!Ttv-dr)P?VY5oysaJ@(gP%9khPrr1T4xY;PcE;Or33aG;+fDego zA)c>$>z*N&vyHCq+={?+3LXiJ~;A z9Ng5muJiQLLF8ZBD6ugDXrVY?>8K+vj*Mi*HAQJNmrBe<2(QEP#Vc;}fmq~Fktt4x z3y#ALr=zQBX(1BRIKeh8O9GPGsFzyTe--Te^eLgC;V3)C zRYu`>{bPksIlgT1nW*~8fUgcqgQhynsy4SU**bfKIbBLp8Kw}5l4(J>j^sUT0eg@p zqDbax7GGc*36m}bQVjz_)=Zlk$kK-IqX)=im``ZD#YE{xQ}g2VH!YUf1ywODIDFs8 zwb&w)d5*xTV1AOkj}%`%@l!#w(5krt(i{c^C+3NM3iekVbr<^Pj2$*y{TP)l{+2mc zOn1jV)^Fi3eNnKkW8_neqNz$U!*D~iu! z4N~IqgHKiJb^m?gO&8amrUX+xLv>YocQlIitKDj66RXjnAoN)*=*hR#B1bnKPY#08 z;v^J{04@WPyA)FTEk|DKSQ24<6wCY=zdG#QBlI9HA=2ezN6sTYI;|g>yxofjENBE( zUudnH6MIdWSodum$G<7|2n(b(A9p@WNwVPCJ8c!=DsUw(>4LV3^Da$gbgr2R)Yn%?KlX3VF6iRL4pnJ< z-R)R-nVp=#`@fikl;zC!oqs?EJUw0gY7*=X64U}Ypy+%bOkY-PAl1e7xjFI{saE%F zzW&F%0Q3^R))BuAFR!@ZQR(FdY19f-7crAJyxnI{#)${DHxl?KyUabD*cpEVRp{-E zlP?XA^(_AB7Y%V1ks=xaVX|O$om&U{y%HzmQYG8#wr|OFDs*#x{mu1_Vo^f7yZ!NO z_1niqk2}qmRk}{dnmSBP7J`WX^|IFz+c84pjEtS*3%5Az-%!Y|vyrW0lXUDfOV^;E1Z|8(^9(_DZu* z(a;=rK3kYAD=Desd`nm5;em&Xi|Ortv5THc!g9H= zJKm8Zlqwf6GUo+3{jS5bo^sn`LXYbmN|EMrMO;d|o9va=Orfrc3CS>AXcbvS7tTn^ zz72$(UzCqQ3CHIS&g06@Ktw4nf=6+uKy6Yd0UJc5)gr1dS>Zn>qdZ z+16!Kq7PDuD>U}P`!yxX58T!$O;Ac#EYV-enPF~H_1(+4n6vO*3cHcISpCR8OIq~C z5zkT>rn08S0Jn{h6eBr1Q?>)wp9bREy=f9p;eKZHYdnXojB@dGH=8#X{+`{_tGHza z3E9?xh4U4-pOFcPzaWn`>4u6*O{Qt=q18W)C!j0VNLz~qUc*o~O9j|j-qghpY-t!M zj55k28z74$uv^(;2R!S4^e9m^UST{RSe zQ`ZQ(oL)dP&tMVv@!=BsuAQ*UsfXpS8h~8Q!^*g^F}*^@co-EGYe!0nOb$B^_Z1gi z=u-8T{7AKX3wsTI9WDlo@LN*#Mo-6TB|lUoG0>JEwzzmw$J&Hiq7vrT)nzVI%*;$o zEYk-SiRHzq(nzsbn2pa85|WK^2NE(Qq5IbJmT_isD1}SFCSDe?!^q6<${Z-qfYPCU z!&5c?# z;n?OEtOo|bC+(rr3)Vh90ewAWN))yt#Ty%39Jnxe@>o7eeEbZWp1N9JftcMP;AlO* zjO~TA8!m>~Y8FwK&F>JiVQ3VmoUq77{Hk0wC(r|SJ@QIQY9b)#Zlmu@O&tLf26{-F z_}!N;0e*~Nn751Jv$(a+vM5cCW7%C@lTk0oxVVaHXQD~bA$aec{rpf3*1}wTmekeZ z8pB=%pW_Q1l=32xF}Rs_ad9b!y)B`Oe_bLmpu-uH@uC%d3!=pHsMP4O=B84;xl4 zPnYGGC2sbGx`eY7$mnFfen^8TG`a1y{rpDTkdY3jiyhwZ^S%NQwXb9mOHG7Hnpd4I1?AHwi>k&e`WWeCqi%4_6s<#|wS z;xX6!aCyqNdzqb07tP6QnVlUF6-FvcV%q%Ml)aKcqklx$pxH6U#*Dc|H}n-MC}LUf z%a^uc0)nz0GECRPK;}?k199f+BiBr6IH<>Ky0%5kv5QJL+@0U*OgHqgh5acT+lv(v|?u)Qj3YX zAci@&Y2rR(9D`^~!sS+gJ7~bD+4yz*A-?nnIRa}jl~f>Z+ZGB{>r$>N>WlEqZ9`H% z+~CYw?#p=CFka3h(zo~5=uA_(6VaqD?&j&xGC*@ zQ;zbi02ODh;nG6zmx_Xd&B5f&mB%}T)&(WsaccVW(g!t1Am8mz{k(2j(bwH+57|7N zdn$jtR^-C-r!wUd;eH~ZSK#A?!C-e{ZS6eN>;Vr@#!2avG4KQ_5u87qo3#eR2rx1) z^oB3h zT)W^qILBBf5D33o^Q$Zef8r382NEubc_BLnX~M*P*38`2dl5(z4xC(YIn z2p5}Cy04X4O%?9&o$x(JlEwY~RUa*wKtlsy*23cRo%_=hsK>;l@ckkb!R+?1C^;nY zJAdM+%VEgN7tJKL?L1U<;oatL6<=DZ5-4nlNA~u9)XoS!%--I?C&*yJz<4b!0SvkA z`gSgDH@RdhCkOsrYJdqcbX*(1*vo69vNC;5-FUoTA^Vyf3j(QWwi_6zsd({iX}0Y0 z(lFNNcX@G)Y*BSy^>|r}yaxUoc?XcQ8?yOJd03>i0fQR1mEwqi+lz_SgxYFT zznd`8Vf!W2jMXr*P=0Q1u@e?XvjXN`K;u|;n^CSGL2S^n{@vymmep4NwNG6x0WU#} zv-^dDS4sD`Gi|P=s`TmJFWyE0Uf0(H`A6vYXlPi+I~LcE&HS;OvR%<+N@;Ygx>Y9{ z>OffQFbnKkny*OVh9?AGx`Zv&)+%>fK`+DEL|7NKe=k3p9TO_LdyE0wi-tyF^>ce@ zvgtXrXmu2rl>!1rCLoo>wkr4e-dpQv$qX>A^EE&#j06Q;?>!w{p}vAe{ZUc=#Td_n z6NiV9YpZ~l!4_)tuo$Un=pygk+-5boxDMl_-nIZmf<7=IDJfTHJ+PpI{R$D0?Q)6c*Ns|J{g=U*<}8Hz!5EGKk12k} z5D2)rzP?@DSi<y!rXmpefaWnl#Ln|^c+3M3yx}4#M=65 zH{12xjKGyKApKFGs#PU&%an)^70#GHd66QW+kSo{W}#RIAOROL``u~BSLDONT02CU zgM)KxSYg|spqi?$SJ-f$?!gvs4kKnM>u527vuqKZbO_yJk zgvzg1FvB@6UKD*<)^Bhb&^Q-#W6IRnc!)g@{Ptb3?&QEZc4Q(Cr}Bb2kZOCrv-A>; znR>3g%Mi%v3=AQZzEn%uTs{}FA8~U8m4D#l78QdIjuo2)t3|of##+YfJZ)0ag-fES ztwZlcm}JXUfHS6^ZA(dM%R`o>=gXNUz=9(#!2z|_+1ktwrO*v?^AmZ~px|bPq;Pjg z+#a{)B7iGAJ(ba4lx|~zvsg{t3mf<|q^QMx=;iYz=rz=BfbGJ?*h}Z&C=nGCNqqXA zQ(k}a;$p=oL+1@l5wtM%09BUEMVDo}TGg2pEOI$->QSDeH9!XCc=_(b1v% z4Z}sA^8@gTV~x)4Q+3b@&!7YhxLHa z4S9x9tivD;xsGn|8p5kka1__fG~h#cfBV}cl%%^@oD7xCfR*S^2(yyBn}xws!>m0I zFyP}8r5Wr5_{J3nOv%u6ic<@mR=jDR)%~fdG6OJCr;r$RMP3g+emg$uHRDCJeH&qz zL9|iWECV?`fm2{^utqsAyxvBtquA^$O3Di);uaLYbM63!(?JW_o2WDMz>0us$%LAk zK=EXg8F(Zlb=FEVx=93T8hiIf~}ZO@Zgd zdmT-bVWr;NtJNUb`>x}*y-=dp_mAOB#z?FrgZ9WJSYeTUgoLOQKNzqbyH*I>qi)WO z66bsvbrzAt$tp}fucL_tkP!Wp>_pRBo<+%1Zk>ldGo%WPHC8Ues*5yYX|p=OBRF{# zA*2bs4`J1n3%qIerxGUDsXLv-&6^J^) zysE93r?i@}@3I1n#|Xv+W-QbV(D{*c0kReAh{_=M1_Vi5AzsDOFd-8o+NQmOC55#^ z=4ShZhmBaDr0GKA)=uqRKW#=u4iIB zr8lUi#!l>~MW3@zVe+1z590;9t_Eg14pa+p;Zw%&D6n{YbQTS3dSli4oQj$nQGO!r zBw86q46|?RHRKC7*tb%)fzQf;&w4b@Z-bd;tPg#Sxy@UH`np2l`1$kWloUCG0M^N- zcGtjdiv#!$e*yNagp6-?XtA1&;S73P;*|mC@L}~0{6o`2@sSj!(X5|HYY2&_#oD1C zS@|csCBJp1Pjp5h&XO+O@D!$=9S$4ve@G){q8a!730yP*Lm-s-=>h z+%{XqYTw2p^p;@3^FmA@btfW{drww2WS1p%3lX(J0;$r+kNA{W$tT^SMUBc}d=5HZ zRZ=Xm10s@WYxsBoI{C4Ha9bl5!`qp%mb2RD#Oq-&nb-R=-HAWB?D%6@!;<%4;nwsU z5qsa1I1o8EztQvB^!Tci=&({KbOH%{dX-YzW2LdmDE&eciR=_nM+iZ!`)_GJPff)( zhu2hxCOEr=VXVV^k6)U!WAC$7sC+i3drEr}21d_^c~*^wN;%#BhF6=nb;N<)k&j`w zi#5PBG}`|)X{~k7Wh^OkV8FnIqE#AJQ0GG2L-61#JRt&g>kqBxn_4;$*{;qkV?&wu zZ@xqXBUBkKR?eh4^9exN!dXTsgjbREMvI2rsczd1MJ_e7zMyu+43o*bhO8O2ym{7( zKg8$%+^0*NW%N1waOTEPuN6`r{yM`hV|(-)OO*C@je`SVAGrrN`Erf2JD`c29ww3e zcHHtUU7*e`RVW-2PaU$>G0KR8AwxXskqx(yA*Lf*HX(TIHvHH@5-;<*;oNoIJ z^suw}S*JTc(8VZsK$au2)p_nroDk!gP%qu zWZ$=`hhDYOb8);C^+xzC;{IYn{Np-T?-_-O9Bw*0%4!&!4Zo1QcVco>R7im+hI618 zb*>dW1jYbL+DCx>?llP{zn~gWk8c^IYNF$>B!!?Tu;C~u=Q;HXe6 z>}_eBeW+GfSZE+9FuG%WeQ>;F%7ooHR7{d=xVrD7kRa0Pi--}9H`==6_7;C$PN`4pA9vD@OS?Cbea6wkoAV`>KG_n+== zl^LUa-wFz@kxDSiH;Oo?!R2&(?vw{RwoxdU!`Vwe=+noK(xFgL){Mq2FQ2+9;v;+v zdfv7wi0ZU&6CI62*WL)(_}WhNynzZM*cLf$oQqC?dSz;E+>I6cEf7@tO+B+;R`H&3vlDE_!TR&sa;lt&|>qr%-zE!P*M=WRs_W^Zn z`Cu?Tt25(P-%^q}hIiZseq*LQ;>j50cPu2NO{2tImlx7BTTNj6`4&-0YqjJCFsWiA6lvmKr97ak30`N{yqPIT0HhVQT1klpMJ?k&MHSC3=D zR*s+*jUWB8ActLYW4$N_%{&aMXKdqLa6NCc7MAsa`k^nxwg)+~plp?hLm<^mM)dei z-OJSrALmJ--z+fnEOkRR9&_9J^&i&P!R$KPsIDM=^bns9tf|%6(v&Ys`7Hu2KMMb5 zsSE$B2M>)9ys+Y>zR4fR6POu9ZRK2VUUwpuA%@?nAw1M4HM-utlAF350 zh&ozN=O31?ayhHp)r~eW!ld6Mwo`s3+Nb`G?BKQ!<&g04si{fujZAG1_dGa2d#3u% z0ZYa$sSzQ-dRsKME+9bqWYbk2I z0^Dw_AOrfG0wWkM7+LXEFmSE`Oh+sQk|bBtElbP5!1PKwQXMvIJJrQ9j0P%6TS+_0 zs8yIlyKE5Rr$^S8;y1+6h#u49+F0MiNKrSGaPYZ}MJ89Gkr+JD1J>yM6-Ia}dPvbM z%Lxw5`4I(K9|q+m>k!p>+K=m)lKe^Q2j;bJQ1_OSt3D#OkWhxO&geP=d$mz9iasp$ zi{1RC##dj7k~U%mR#*j4~D`tnY z8gCrTejl?fW>kZ>+godwlN`kXVOE+b=JO5XLRH`}!^sWlulV46EsD(=<){7~ha81%bO=8`@S`3d{$Nz%wrJ*7r3BZ1+~W$V>?_%O+$Cd9k`WWTHvUEOl$i_Q~TRK{K$=kL6nfE1=jL7eEQm2SmBBlJz`^*A2H5)40pPS#_)btkA}8g2ERk2 zpT$DK3QKblAHypinutr5+rn4;E(tTjBGzGT(^PlTPM9Z-+`B^{rQpsF4#39sYqxZq zVlU~k8n&#MI{f90c6C|BaH}c+SFE!Xjc<GTq4*sg&nEp{0rk45~+iK^{kb7LO=c>WQ*k;i5uC6ta zj0CAqzd?R)Oa)cbZ*JKG+k!SJGVd7t1ma5;JlY^d`70CeSY(DxyTmc#w&J1RufVZc z^EqanZbK81t7H8z3+8p* zprX&<_Uv>x9{QtV7pcV;jHCN*ORxF*>E>4gMGo8hQ0+2OC(8rwgnrecz`6L-j;co& zF~KoJmslk@;yh;*YEi5R1vUG`M&xtoKvkKiSSALxiz@%U{D}H)nno+e;B@o}UQS2> zCdn8_!iQIb#ak$8ydG4~I)ZdOf^#u8LI)lJXvnPTBGCObgv(uyd#AM{Ae=QNZTm%V zD+xY0<6Y&iGYZj_9EIi)y(%!Cg1EmpKL0MBAj8+8&t?tvov}}x^l8ql$n z8MiWqS^X2F*bRaq#nqD}orrW+x2lH+HcBWmV{@>l6;;l7y)mvp1HNE5wD zpxwm~iff^R63u_b&=F>(*pvZ#al`lQ4Hw|eo^ff?5i}adZZaZaHPdoTc!MaEV?rH2 zfS#Zd#Uan4`8ASv#1dYevd><>{{x<~Id7)Ufhi}7MC8P|ECi!g=i&If)GsSRgO>j%_jD#V7 z0im|s_1U}VPT*CWkM}X`6RL*na9OB`*F?=-~3I{ydJI#pA z7=D82a;CVuP*D|-qPGWIoD8Y_Tw$PD?yt!fdTMOt?$Kt9d{Yd4PsTQs7GN%Cg@|Cr z>l&P9gm%6bYAI&)os)^_nhMiO)hMO85c2C3gee-=-5shM0n+e1$bwJ`MpMQu=e{^; zcCU9wHc8+$%EXnw@9M{I;tmAwc@?pGWC_g@?CuK+5s}NlTn=Vv4RVfDx5GAtNE-!x zWOYZ*(=y<5eZ}ViGQ~(jct?fAJ>;&u6lb5+(=+)p2BjZjaB1rupAZG8Luu3);DP-H zSJJf`ISLhr#1lu*6tXHZZG3>=gB-c-iQ24l5@f`TZe8J+?0v-4l6*XC$@drFLn>b& zk{hMkNEa__&UWQre`hm+5FruHm@fu7rq-XL?XF_+T71VI!g4%|ib}p4YrE3AJn3<| zNM1qAT1r^V2U|0h*jB*@Q=`m&P{garFC4agdw9XkfO7ThDNj6lMFJ#_|2cm;AXd5p z&=#9jSxMjv<@lR}?~9j?G7NM?L$r%6l36JcYS#&6a(dNST5TC4|FY82WWn|IR!$D_ za43@f>HP6Rp*WKH(}`L)Oz*z9A_B~rbOxTyF-6qFv;oD^#kcjZnZ{H4`sn4ML_PwO zF`9S?1DSx<`mpS$5;^_rl}E5#Lg;m&cs86(sb^d7OF$cbd&m^>^mjyA~RVh0%>|gsF~O zGPM;MjR860@rBvWO5eoHFmx+e0hnuOZ>aRcpilh&1`CBy>+?3bfunc%H z6!_#7v9ttw1CUCh7w`sJ8sJ`4ve9S(^3HD0?*m*sa51h@cRQ9v& z3j!g%jjN)b%xO~DKgyqzdlnQl+CNj0rT7^=jyad*jf4BapG%GgD%c1xF1-^8kE+yZ zYB5|A3D-7Ou>!T*m=V^=JkI9qXAwnD|c459yedc;9^VZsXxzUUbRu;qCFAwM( z#|m*P2w}u9=g@!FplHB!xZ=&K;?%;Vl4qoVBf;tESUBL%NZJn#o9PMuSxo3DfAaGx z9ykjBpQbj;f&?g-Tfa-uUAAFw^wR&W?dvy~6$j>LvHaBIW^}SzaT{(FYrJi+t9eV` zjlYl@bFwNj!6{a$s;SXBbUXD3E(0;@0q0sDP#NC#1~0R!2M zWslw$a81yi4S6%ojHOWWdHeW^4riDWe%a4(Q^Wou3|xjDHD8%2?1m zX&xu=PA0w=0S7HQY3BU^l#lQ(6&2wrPIL<+Fe2qVaXlWFK-C!`zP$ROS6eF^Ol3SX zTPH&&tUx5I7(tnc*6#Ad@<;foD4RPJZtYRq7`i)Cn?0nVhAp;*dUiMRk3=8F946!n z&Qs&1h9g{r^fIyI(!bN;L>@ZvQZIy#a8{~9;)Vu@)$oOCF3+DieiHcsNn%#o5Oxp? z2oye&xiw>iYTMlcF@1CiUL+av5~tllq^3`ufNM>F(Ip?pF4E-KoD@ z*SDt*;UA&iPL=!nS~t5`9&}F|$!*4d1DPS0R4HQb`w7^DkzVa;m*vP-f6X_-GiV+?`j1 zH94hVby4d7;V8cg92~CSe~TMl=njJ>8RbPzK--Oeq2f)?Xwzyel{Gc7 z>yk7$ZjHNz0tPOYV=ot7`U<3rIk`+jzG7p;d?_ce`hAX1WupnU8&5V4NXL`)ERB?) zkGLWZtmP%UlbEfG(4q?^!QDciXHApk4JSi~p!(nsFo?_|86e_TG&b&wjE0>t!>8%% ztA>PBo1Y5`u*Tf(EG03jdL2gOZceFz^vgg0zMnp+so9TIYGUp!b8Tn9%)|7)2|&q48!M6M{!IV&Jl0+WNV}{^6l?t5Ve@z3n$XU8Jz}zr{Si zu@(&BLAtGSm)~N^7$*gHMz=mX`4mUPX_Gi4{B>TO<;UIEnsFlhPk<^oSG?t_CkmY+ zqpNRxu^CfUhjxswllHPA4gV&T;%g#I#>) z-oFeQCwtg+rYoX%;GoOWP5tP0~>szk}yF2lu=CG-} zS@l$NDvmlWYv^EGeN8kXJW{YgNYUDjl@8;ss*k7uiAjhiS$j1parV-M{s+3X4-194 zyT&qruOdVgiIK`FO;coTw}f}A67G0pz0|eI%#mhv+S#bn_3U%IGwMx^n3PrLstDY3 z^U*%Cu$UIvwzu`oq_zx_;}aBQIE`StC)7X~T@kfZ%K}ocjZ}*|%-j6>maW^crHthI zEkGkF8E^U)5mp1n6VOO-o&9b{|p!}i36xF56FWP`xp8d@{sKu zD(jUXlg?c(axTHO->?Kdf3cU!ns7Zl$R=0*z$xfjps@_p?C8NXbkl4_XD!X8(G|x|&QyNL;8Lbs2mbz>OcWczrQtBv zI|nwR(ndNWx+lV=1cf}lf4_j01U?cR#ry98*y#VGrFxs39GH`2T`{sw&vcH8v;=@? zxK(W+EWKrEipH`=-mJ+w524n_L%19V)agb2A5tMwp<|K~1x1uUA0q^@ffgXw=@cyl zVUIM%%kaqf+taa4X}1{fGlB}~1J!<<3L}`&uVv;GX##hcTKI|iU zT<)wa82}0Yu&uGt&{n9RSZUx!@Rk(|Zd8l>V&WcYW!U)|*{Jym`lYtw+^^%Ea>RdUbAv>y{{`GYyY}L2 z7h1!h0B-LO)t<@CB0`j_aZrqTgRMN*_wjL#!#`u3YhLG@iBA9euGVV=F*xC|O1mW0 zeGE0tV^WkSHLrDQV}BT}Fv*;jY#=L=Qn@nA^-I#PzgPOlE>wDYT5FNV#MN_hO^_fh z$*VCG@QWVxBQF`O6;MpvQpHggRL5**D@ntyvo7O*M*bn!$(x-qfj?ZHBdaWHIrEvbmPU%1Zey(|iwTr9>$J~VgRz#-)>M%Vvx{!&;K^|vz$OcciMMQJ!%Mx-??6VL0TZ4g;r9xwhj0>|+3vB;b!7SK7$if;NtxFe3K|QlDjStmcz8eF zFhjeN-l}QxA7m6eMmV|8OO%b_bmLcD67g7AVj6u;u)!>gD^cH3<3BcS4;J`~Bs|mn zJBkDn8P<&v{SPwxFMfq_N&4Se-#71@t!wz>ejH<1Yhq{F-7tYte{;l&!6yU0`F6K*AmZHkX8mb>_HQYT{GDXLM?B7%$cm6P_X z7v(1VGfZ&$dfPbMYA)yEX9SwLH-U+!-ViA8vl|K1H)rr^)ZdzPO8tT5kFkb4<}r!D z6DBcA=GkEy~!6YPYa@45Wb-c#_}4>2CQxi!&pm& z2hkrh*0|{4bG}0L(2vGU7t~SQqlx3g@Y~^TT{I^{1ZpSm{_cwV+H~#t=uO-! ze8)|09I@61ucto?BK&0e_tTNmCgDp0m}imZ-<^4-d7+q3{r;@a_nBJD&9Qi~p82mq z4F3Y3mjXUE?H3|@`2TyM_`Ch#-P&I>^Tv8MBX72@KT{qz^CwU5en!0rKYV-DfAAUm zD$I!ildsh9{>kZuclPx{kcJ3$cGkDGr9ENjjgw{>ET1dRwpXZxSFRcvlac-D`d~~1 zulI(c3b~D`9HnnQXuTNdpOZrdUd)s-47{Wa1E;sydi-g!`|9*+f}Yz9vAx=J4JJiR zJ=`MjnP2O=8Kzol%o{yadk7o2{kq%qYBaPe_3KNr5fT+>(FRh;&zex0l)3y}vPd*- zI~m249gcpq;((Y#9b(Yr0W9Noj*c~beKxsb2{XUj`kt-{}Pj-2hERB~&YZdeSn_$V*UUD67~Qeo)3WJzU8wt?T#GAfa(qO!Ki zgvle(3E;Soa?553^6DVNQH`hRelznm3cu=@E-Ykf!$?{D?jinht~L-T5{>U9E^w6ImQ@OMJxl_Fs&e|lP2#OX)jSH71^Yb<1a<-^bCv|F-SDqo1E z2@vBy41T>iPFHADzs^4=jRRO?!JGZFmPL1N~`dG<_yCP2EwE_InUYVK~EuU>{1!@QZb#sNjYafM_EJ4m96z{btZuKK>3M@8uNH`w zKt_C)rv=wog(sodkM>qwTs%Ecfwd2P%|HNhe-w|0&pCl;>?2*n?=3`FUn-YT*(p@1 zM)D9NzJ&wpKXereIyfnWm#&P)P4U^|x*}ma6n>(e1PU&oH<$TYL43bzA&FzAE?29P zqE}1cDJ*VPYIIh`XH+K)w-*F0Jw*seN&mpd$?n?SeC4(*6gZy^id5eAbRN2Op$47F zo#}{Se=ipuc~rz{UPK$Lmrg7T-n`X2GgMVj6E)y5Y|yIKA++4xEks#r1-S?xYW%LA zmZjPi7M8;+_%1AF31(Qf3E;L^x)}hMAJ-qCaM{Wnqi~h<*CU=eP3He%E7Kf{SQ=Kf zW|50!kG{IPIIVY`3I%yg^FK&4nIVJI>Dim^-EuSB=2(_SSzIF3sPwYLXp5@INm>^F zq=$GVI~kkO)JNfv()zV=_+;0=eqw$g!?)jVESDo;dk!t4eW*JqAPGTz`ZPV z%)^vk4F?UTd5QN^D1Xl&BHGA#6L}W#-h**gfZ7Wg(z(>|kR4u^B+A+75eSvLe)^EW zkjmot-@m-I5q&H3N(|OQ(gj&w`fyR6@^kFSwiFc3m0oyrUre2~^ozZptdX5@7|j{{ zN#!0^q_GU~eZGS?4F8h9#8>^D4ynO7*VnZ!;(f}W+&bZo6}3DYz@1jVgL0s$wh=W> ztVJy=W+T_Z!S|Y2flaA&TK!Ay>Ggyx@!|8`me}f^MZj~C+;WMY^==DLiWLq29VRmE zDsJ&jzC~!F6aTb`!Ns2XW}^>I38-A@zSkw8N15sSJm*Le6=*`BGPAz*v@#F^&#;11 zYbM&nFmeSSWAp8a#nyiG^h_UwnPj8Y_&75%xSBAveq}P0N4h|l+IvIjw!8vyn;K1f zfF^XTe;MvF48deJL5kRUoHp>g1z!#(ay?dsa?nVfle`$6qMQ*P3di0dx|{v=%WhDf z6`5sfP&`>#9cHpv?=^4dC)cxE%`JxOX)z-*CuxOuI(HDJjkz-dwV(n@pXSaZ_vO3_ zR1>dlG%BHrSG@RQJxEwHK|m^i5}>ZkD1!u|-#s^DWYquE^l+8%$+5O~C^E2$f2{un zC-4}pZkh_lK*upe^VD99!Av?=zK>2AQlkB`-a5{QZhJ?S+wjC%y+m-~v~<4#6n53w za?E+jv-YI|Z1j`Bh&d@E?Iun)nNI^QB&LE7Hk0*Q;6eDhOVr_RcGw^qZsO9Hms+9t zV5Q|#XJYtklx~{VOIpF*k=8Gz4x;vSM0QNokO=v?clc(`6SWj1=`K-ui*cdOCMy~6 z*+yLP`0Of5>okFR{M3m{b#)2vX#~pPQ+)fRThm&g0OT6%qnSdMsrB(Blz zb);0ee($RZb!VEsd%Zm|vT*lRe2+7+`OX4CoM_QIo48g*X0m($)avQM;w0e*tE;*0 zESKq`VF4Kb7a~Z1L-^)x)w3k+mq^LEH(rKD@_1fP()65F*)hAe!Cw=g#T!-oIZMXt zIl}vp4sfgi-*As2RDed_fPs>^Ki|`1Fu1;DeMx@WD*W|cZPV8U-zAMYogrwA9%&=X z6`I?f-wlj7rcsJ&>u+nMcK8B;v2Cn)WxJsr@JHIp`6P6~Y%7jh*iwf~f<YnG{f4aHBGynkZa(tSf=rdMsf(Q(J~_UMiSaUn+Ys1X_6tt)w_kuM5{A zuFq5E(U2I%`$!9NaUc>!H~k}?U7#`^L>?DQ}C9edyVjbk&}D`s;~ z=7x#S;zV0Lxpv_Pjdqd(+K7tQeMQnTLarZx@j8~+R%x#AsAwJyJ(jsUraDN|rDm6r zN|d@GvIU^9hn>Lkhz%i+)PpWt+XJy|0@3-kXC1*j8VKaxk@e$L#_nZ{N?Z4Su=;;C z!CW@WUV|^7(x9qdzY{glpEgukFft8xUtsQ7bAQ+c2?6~tL7VSn2dHYWh<^5(d7}qF*uqq zGm|l2q?r}<}u>b5pLZn*H5fR!4As)&UlDmtu zx$LK$LBz!3c@YV*JngiqbnEPY5e-kEe4!f`o8gayOMO8>&u(MuGcj#SdY_i7ZLd`l z;}P&3QPh!ZsHJ7)Ox_k~{wy-f>Yl6dGa~F9g8WlF4tq!-_WAR_Pb&C9S4P00v}I*o z1zlmRa;=tJ!~ev^-0hQc4v=(FHtrW8z{S<{of=ryW#nIb8_p#tN0TJMbD&Bt4Ueut z?wsF#`6N;+i&A^ny*;WNg`cp<(iA<})=+GOst`d1y%~cpbc5oq+gsRhgvzN`3`=)| zmAH4eM?rrkeylatq%H0sl%}B}R^o3ETi#M{OHTIcszDq$ef={IU03gIu5Z%A5S7eB zv>yPZ{r_nJ_*AL?1TJO_%}~Ps3ASEDW*i(dc6Ala#HPwidOQattLCVYR$|Owx`4p8 zK&f2{pX>>4c$==_VGAi@F|SNSvTsw^(HC?bDP`UZBhM4pffE&ps*FWdO)#A`sY8P~ zpB{zs3Cyd8gYyc*Jl}oD3kSi7ykg0G!NsjcorS`(nwpBL@guu$zxTce_rq#Yve2yG zYeX&p8U1><;x%mQ8)w^wJosS0AQ0>}6tAf|2w$ zMg@B^%r8+PHH>qz-@b+WADW;{l@caGk@HSDl2lh#OJDG>A#Bzrz*l z>=B9R4eL_P5e4=&%jb8tthwY0@sTNLhwWyNDa2$j{~;=Zcp_t5qPXT18&L^(e?ZRu|Bb^V1g8k>3<{Ed)-(g7O z7)`KP8%2}pC!}|+hngC{?7YyR$3QshAFt|rXuO0OiU;cEMOz{xh%+2wNya7Tx$;VE z2dQo}WoSGWkI~`o^sjU^RwtRI34`9T6YlBOd^YTbpSAZ~uz-%%qdS6&`(Idcl&6IeDQyTAs>$HVG9jx%QinXjp z7F@v3=lfQM9v(uQ#KseqXj4X-ely)0#cu6@e-VmbI!~{ZJkJG_d%XWF`iaVLumqxVQb5FS&1J6C~?#~Po!)eB7F^WAeXH~ z#=Foeg$}k3hF^+Ju3nbWvc0`#ZXI$5PH-*h)r=%nU(7>fGgS}eGn6pc*IO&iytE8} zN3zC9p9{T6*;0>MTEJ6g7+z1BE1YjZO(f;uObydfGi6vLKbY9ng>`zQ+Gde2fH<-? zi$_;DE#97(j8!>Vj2kbE1E4g1e-k0LFQsVe)u@|6;$}bMW#%Bl5{I<6@>_?BzM+?d zF~XM)~)xs+Z^Yh>uT?RvwKQM=NhnamSt? z4{8@HiGHl`v-HMZ;7k@*Djr>x&X`y183SR-FJwr(0D%$NQpe7EUDJn~94tw1tgLz@MrLV+}L@*CeOp4^8H-_YL( zz?ORvwEu05&@$zS8PM>Sszis6sJThzeC_9q^T+b<$Y{)AE?D`oHKmWVruYcP=+mo; z^X%jzViJDbn_K)oJ4JbFDH}?BnHLuk60lWL#(O8D^#LR-6mB!F>teQ7P=0Z=S4l14;9 zBWFAoMew{}03u0vS&qd2nEciqR$+9LpXtLm#QO9Ei&5bI`1%iD-xChPJSI@bK4Z12 zb*pIXiP978x^lltK8 zyXK5O4AAi&y#$1}@nAH2(X+O6b7962mJV`)yK_;wysp9vl+!d|szB>}U zA1&~eka2M|-}ruXr_pMeQ;j#oFP!1EAQ+082M!Q5;CJq9G|NZpv4~2Z>0YPzRm*R! zt;5nUU5aTIiqER8Zn$8QB$zMK(-O!p*7F0GE)H*@(a2Twqwu0WMM|%Gp;Tc)lF`fR z;o*Xg2-6_2ut@8+=j%5T(m&ht#oA!`4>YnNLl)(QFbgM`0VVj~Z)$f~zRiKY>DM|~ zWn6>jM&q>kd_zm;{wqG%T$}#|e51kIvzpZ*aR z&XZ%VW5{P5^&KIxqHv}Y6}oTt5S^`eTR|b*Pcz&Y%*)E2vj{wFWDD0k?Dwi0^xnyc z!CdlDO~o>1)3_qw$4I^tXLfw1prD&Y2g=y6Vd%-i}i!y6+o?)T@- zc+K!1VmChv=HqzZ$yYmRh!f-ahvyTat~!NsB|vi5n}q^ew#LyCBL=HP^o60_VI-Sk zU~sON7CRms^Tffc9;QV+{K6}vKnA>ViH^`w=B;6KVAex}|V!O>>?wuEoPg3Ef` z_Z2Bc51Q5m