kopia lustrzana https://github.com/Aircoookie/WLED
				
				
				
			Merge branch 'main' into aws-queue-0_16
						commit
						7c05914e5a
					
				|  | @ -24,29 +24,30 @@ | |||
| 	// risk to running the build directly on the host. | ||||
| 	// "runArgs": ["--privileged", "-v", "/dev/bus/usb:/dev/bus/usb", "--group-add", "dialout"], | ||||
| 
 | ||||
| 	// Set *default* container specific settings.json values on container create. | ||||
| 	"settings": {  | ||||
| 		"terminal.integrated.shell.linux": "/bin/bash", | ||||
| 		"python.pythonPath": "/usr/local/bin/python", | ||||
| 		"python.linting.enabled": true, | ||||
| 		"python.linting.pylintEnabled": true, | ||||
| 		"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", | ||||
| 		"python.formatting.blackPath": "/usr/local/py-utils/bin/black", | ||||
| 		"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", | ||||
| 		"python.linting.banditPath": "/usr/local/py-utils/bin/bandit", | ||||
| 		"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", | ||||
| 		"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", | ||||
| 		"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", | ||||
| 		"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", | ||||
| 		"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" | ||||
| 	"customizations": { | ||||
| 		"vscode": { | ||||
| 			"settings": {  | ||||
| 				"terminal.integrated.shell.linux": "/bin/bash", | ||||
| 				"python.pythonPath": "/usr/local/bin/python", | ||||
| 				"python.linting.enabled": true, | ||||
| 				"python.linting.pylintEnabled": true, | ||||
| 				"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", | ||||
| 				"python.formatting.blackPath": "/usr/local/py-utils/bin/black", | ||||
| 				"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", | ||||
| 				"python.linting.banditPath": "/usr/local/py-utils/bin/bandit", | ||||
| 				"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", | ||||
| 				"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", | ||||
| 				"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", | ||||
| 				"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", | ||||
| 				"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" | ||||
| 			}, | ||||
| 			"extensions": [ | ||||
| 				"ms-python.python", | ||||
| 				"platformio.platformio-ide" | ||||
| 			] | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	// Add the IDs of extensions you want installed when the container is created. | ||||
| 	"extensions": [ | ||||
| 		"ms-python.python", | ||||
| 		"platformio.platformio-ide" | ||||
| 	], | ||||
| 
 | ||||
| 	// Use 'forwardPorts' to make a list of ports inside the container available locally. | ||||
| 	// "forwardPorts": [], | ||||
| 
 | ||||
|  |  | |||
|  | @ -37,4 +37,5 @@ jobs: | |||
|           prerelease: true | ||||
|           body: ${{ steps.changelog.outputs.changelog }} | ||||
|           files: | | ||||
|             ./*.bin | ||||
|             *.bin | ||||
|             *.bin.gz | ||||
|  |  | |||
|  | @ -238,6 +238,13 @@ lib_deps_compat = | |||
|   https://github.com/blazoncek/QuickESPNow.git#optional-debug | ||||
|   https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.4.0 | ||||
| 
 | ||||
| [esp32_all_variants] | ||||
| lib_deps = | ||||
|   willmmiles/AsyncTCP @ 1.3.1 | ||||
|   bitbank2/AnimatedGIF@^1.4.7 | ||||
|   https://github.com/Aircoookie/GifDecoder#bc3af18 | ||||
| build_flags = | ||||
|   -D WLED_ENABLE_GIF | ||||
| 
 | ||||
| [esp32] | ||||
| #platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.3/platform-espressif32-2.0.2.3.zip | ||||
|  | @ -251,6 +258,8 @@ build_flags = -g | |||
|   #use LITTLEFS library by lorol in ESP32 core 1.x.x instead of built-in in 2.x.x | ||||
|   -D LOROL_LITTLEFS | ||||
|   ; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3 | ||||
|   ${esp32_all_variants.build_flags} | ||||
| 
 | ||||
| tiny_partitions = tools/WLED_ESP32_2MB_noOTA.csv | ||||
| default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv | ||||
| extended_partitions = tools/WLED_ESP32_4MB_700k_FS.csv | ||||
|  | @ -259,7 +268,7 @@ large_partitions = tools/WLED_ESP32_8MB.csv | |||
| extreme_partitions = tools/WLED_ESP32_16MB_9MB_FS.csv | ||||
| lib_deps = | ||||
|   https://github.com/lorol/LITTLEFS.git | ||||
|   willmmiles/AsyncTCP @ 1.3.1 | ||||
|   ${esp32_all_variants.lib_deps} | ||||
|   ${env.lib_deps} | ||||
| # additional build flags for audioreactive | ||||
| AR_build_flags = -D USERMOD_AUDIOREACTIVE  | ||||
|  | @ -282,9 +291,10 @@ build_flags = -g | |||
|   -DARDUINO_ARCH_ESP32 -DESP32 | ||||
|   -D CONFIG_ASYNC_TCP_USE_WDT=0 | ||||
|   -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3 | ||||
|   ${esp32_all_variants.build_flags} | ||||
|   -D WLED_ENABLE_DMX_INPUT | ||||
| lib_deps = | ||||
|   willmmiles/AsyncTCP @ 1.3.1 | ||||
|   ${esp32_all_variants.lib_deps} | ||||
|   https://github.com/someweisguy/esp_dmx.git#47db25d | ||||
|   ${env.lib_deps} | ||||
| board_build.partitions = ${esp32.default_partitions}   ;; default partioning for 4MB Flash - can be overridden in build envs | ||||
|  | @ -303,8 +313,9 @@ build_flags = -g | |||
|   -DARDUINO_USB_MODE=0 ;; this flag is mandatory for ESP32-S2 ! | ||||
|   ;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry: | ||||
|   ;; ARDUINO_USB_CDC_ON_BOOT | ||||
|   ${esp32_all_variants.build_flags} | ||||
| lib_deps = | ||||
|   willmmiles/AsyncTCP @ 1.3.1 | ||||
|   ${esp32_all_variants.lib_deps} | ||||
|   ${env.lib_deps} | ||||
| board_build.partitions = ${esp32.default_partitions}   ;; default partioning for 4MB Flash - can be overridden in build envs | ||||
| 
 | ||||
|  | @ -321,8 +332,9 @@ build_flags = -g | |||
|   -DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C3 | ||||
|   ;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry: | ||||
|   ;; ARDUINO_USB_CDC_ON_BOOT | ||||
|   ${esp32_all_variants.build_flags} | ||||
| lib_deps = | ||||
|   willmmiles/AsyncTCP @ 1.3.1 | ||||
|   ${esp32_all_variants.lib_deps} | ||||
|   ${env.lib_deps} | ||||
| board_build.partitions = ${esp32.default_partitions}   ;; default partioning for 4MB Flash - can be overridden in build envs | ||||
| board_build.flash_mode = qio | ||||
|  | @ -341,8 +353,9 @@ build_flags = -g | |||
|   -DCO | ||||
|   ;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry: | ||||
|   ;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT | ||||
|   ${esp32_all_variants.build_flags} | ||||
| lib_deps = | ||||
|   willmmiles/AsyncTCP @ 1.3.1 | ||||
|   ${esp32_all_variants.lib_deps} | ||||
|   ${env.lib_deps} | ||||
| board_build.partitions = ${esp32.large_partitions}   ;; default partioning for 8MB flash - can be overridden in build envs | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # | ||||
| # This file is autogenerated by pip-compile with Python 3.12 | ||||
| # This file is autogenerated by pip-compile with Python 3.11 | ||||
| # by the following command: | ||||
| # | ||||
| #    pip-compile | ||||
|  |  | |||
|  | @ -4450,6 +4450,24 @@ uint16_t mode_washing_machine(void) { | |||
| static const char _data_FX_MODE_WASHING_MACHINE[] PROGMEM = "Washing Machine@!,!;;!"; | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|   Image effect | ||||
|   Draws a .gif image from filesystem on the matrix/strip | ||||
| */ | ||||
| uint16_t mode_image(void) { | ||||
|   #ifndef WLED_ENABLE_GIF | ||||
|   return mode_static(); | ||||
|   #else | ||||
|   renderImageToSegment(SEGMENT); | ||||
|   return FRAMETIME; | ||||
|   #endif | ||||
|   // if (status != 0 && status != 254 && status != 255) {
 | ||||
|   //   Serial.print("GIF renderer return: ");
 | ||||
|   //   Serial.println(status);
 | ||||
|   // }
 | ||||
| } | ||||
| static const char _data_FX_MODE_IMAGE[] PROGMEM = "Image@!,;;;12;sx=128"; | ||||
| 
 | ||||
| /*
 | ||||
|   Blends random colors across palette | ||||
|   Modified, originally by Mark Kriegsman https://gist.github.com/kriegsman/1f7ccbbfa492a73c015e
 | ||||
|  | @ -7734,7 +7752,9 @@ void WS2812FX::setupEffectData() { | |||
|   addEffect(FX_MODE_TWO_DOTS, &mode_two_dots, _data_FX_MODE_TWO_DOTS); | ||||
|   addEffect(FX_MODE_FAIRYTWINKLE, &mode_fairytwinkle, _data_FX_MODE_FAIRYTWINKLE); | ||||
|   addEffect(FX_MODE_RUNNING_DUAL, &mode_running_dual, _data_FX_MODE_RUNNING_DUAL); | ||||
| 
 | ||||
|   #ifdef WLED_ENABLE_GIF | ||||
|   addEffect(FX_MODE_IMAGE, &mode_image, _data_FX_MODE_IMAGE); | ||||
|   #endif | ||||
|   addEffect(FX_MODE_TRICOLOR_CHASE, &mode_tricolor_chase, _data_FX_MODE_TRICOLOR_CHASE); | ||||
|   addEffect(FX_MODE_TRICOLOR_WIPE, &mode_tricolor_wipe, _data_FX_MODE_TRICOLOR_WIPE); | ||||
|   addEffect(FX_MODE_TRICOLOR_FADE, &mode_tricolor_fade, _data_FX_MODE_TRICOLOR_FADE); | ||||
|  |  | |||
|  | @ -184,7 +184,7 @@ extern byte realtimeMode;           // used in getMappedPixelIndex() | |||
| #define FX_MODE_TWO_DOTS                50 | ||||
| #define FX_MODE_FAIRYTWINKLE            51  //was Two Areas prior to 0.13.0-b6 (use "Two Dots" with full intensity)
 | ||||
| #define FX_MODE_RUNNING_DUAL            52 | ||||
| // #define FX_MODE_HALLOWEEN               53  // removed in 0.14!
 | ||||
| #define FX_MODE_IMAGE                   53 | ||||
| #define FX_MODE_TRICOLOR_CHASE          54 | ||||
| #define FX_MODE_TRICOLOR_WIPE           55 | ||||
| #define FX_MODE_TRICOLOR_FADE           56 | ||||
|  |  | |||
|  | @ -199,6 +199,9 @@ void Segment::resetIfRequired() { | |||
|   if (data && _dataLen > 0) memset(data, 0, _dataLen);  // prevent heap fragmentation (just erase buffer instead of deallocateData())
 | ||||
|   next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; | ||||
|   reset = false; | ||||
|   #ifdef WLED_ENABLE_GIF | ||||
|   endImagePlayback(this); | ||||
|   #endif | ||||
| } | ||||
| 
 | ||||
| CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { | ||||
|  |  | |||
|  | @ -128,7 +128,7 @@ | |||
| 		<div style="padding: 8px 0;" id="btns"> | ||||
| 			<button class="btn btn-xs" title="File editor" type="button" id="edit" onclick="window.location.href=getURL('/edit')"><i class="icons btn-icon"></i></button> | ||||
| 			<button class="btn btn-xs" title="Pixel Magic Tool" type="button" id="pxmb" onclick="window.location.href=getURL('/pxmagic.htm')"><i class="icons btn-icon"></i></button> | ||||
| 			<button class="btn btn-xs" title="Add custom palette" type="button" onclick="window.location.href=getURL('/cpal.htm')"><i class="icons btn-icon"></i></button> | ||||
| 			<button class="btn btn-xs" title="Add custom palette" type="button" id="adPal" onclick="window.location.href=getURL('/cpal.htm')"><i class="icons btn-icon"></i></button> | ||||
| 			<button class="btn btn-xs" title="Remove last custom palette" type="button" id="rmPal" onclick="palettesData=null;localStorage.removeItem('wledPalx');requestJson({rmcpal:true});setTimeout(loadPalettes,250,loadPalettesData);"><i class="icons btn-icon"></i></button> | ||||
| 		</div> | ||||
| 		<p class="labels hd" id="pall"><i class="icons sel-icon" onclick="tglHex()"></i> Color palette</p> | ||||
|  | @ -273,20 +273,20 @@ | |||
| 				<option value="1">Fairy Dust</option> | ||||
| 				<option value="2">Swipe right</option> | ||||
| 				<option value="3">Swipe left</option> | ||||
| 				<option value="4">Push right</option> | ||||
| 				<option value="5">Push left</option> | ||||
| 				<option value="6">Pinch-out</option> | ||||
| 				<option value="7">Inside-out</option> | ||||
| 				<option value="8" data-type="2D">Swipe up</option> | ||||
| 				<option value="9" data-type="2D">Swipe down</option> | ||||
| 				<option value="10" data-type="2D">Open V</option> | ||||
| 				<option value="11" data-type="2D">Open H</option> | ||||
| 				<option value="12" data-type="2D">Push up</option> | ||||
| 				<option value="13" data-type="2D">Push down</option> | ||||
| 				<option value="14" data-type="2D">Push TL</option> | ||||
| 				<option value="15" data-type="2D">Push TR</option> | ||||
| 				<option value="16" data-type="2D">Push BR</option> | ||||
| 				<option value="17" data-type="2D">Push BL</option> | ||||
| 				<option value="16">Push right</option> | ||||
| 				<option value="17">Push left</option> | ||||
| 				<option value="4">Pinch-out</option> | ||||
| 				<option value="5">Inside-out</option> | ||||
| 				<option value="6" data-type="2D">Swipe up</option> | ||||
| 				<option value="7" data-type="2D">Swipe down</option> | ||||
| 				<option value="8" data-type="2D">Open H</option> | ||||
| 				<option value="9" data-type="2D">Open V</option> | ||||
| 				<option value="18" data-type="2D">Push up</option> | ||||
| 				<option value="19" data-type="2D">Push down</option> | ||||
| 				<option value="20" data-type="2D">Push TL</option> | ||||
| 				<option value="21" data-type="2D">Push TR</option> | ||||
| 				<option value="22" data-type="2D">Push BR</option> | ||||
| 				<option value="23" data-type="2D">Push BL</option> | ||||
| 			</select> | ||||
| 		</p> | ||||
| 		<p id="ledmap" class="hide"></p> | ||||
|  |  | |||
|  | @ -219,6 +219,19 @@ void onHueConnect(void* arg, AsyncClient* client); | |||
| void sendHuePoll(); | ||||
| void onHueData(void* arg, AsyncClient* client, void *data, size_t len); | ||||
| 
 | ||||
| #include "FX.h" // must be below colors.cpp declarations (potentially due to duplicate declarations of e.g. color_blend) | ||||
| 
 | ||||
| //image_loader.cpp
 | ||||
| #ifdef WLED_ENABLE_GIF | ||||
| bool fileSeekCallback(unsigned long position); | ||||
| unsigned long filePositionCallback(void); | ||||
| int fileReadCallback(void); | ||||
| int fileReadBlockCallback(void * buffer, int numberOfBytes); | ||||
| int fileSizeCallback(void); | ||||
| byte renderImageToSegment(Segment &seg); | ||||
| void endImagePlayback(Segment* seg); | ||||
| #endif | ||||
| 
 | ||||
| //improv.cpp
 | ||||
| enum ImprovRPCType { | ||||
|   Command_Wifi = 0x01, | ||||
|  |  | |||
|  | @ -0,0 +1,144 @@ | |||
| #include "wled.h" | ||||
| 
 | ||||
| #ifdef WLED_ENABLE_GIF | ||||
| 
 | ||||
| #include "GifDecoder.h" | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * Functions to render images from filesystem to segments, used by the "Image" effect | ||||
|  */ | ||||
| 
 | ||||
| File file; | ||||
| char lastFilename[34] = "/"; | ||||
| GifDecoder<320,320,12,true> decoder; | ||||
| bool gifDecodeFailed = false; | ||||
| unsigned long lastFrameDisplayTime = 0, currentFrameDelay = 0; | ||||
| 
 | ||||
| bool fileSeekCallback(unsigned long position) { | ||||
|   return file.seek(position); | ||||
| } | ||||
| 
 | ||||
| unsigned long filePositionCallback(void) { | ||||
|   return file.position(); | ||||
| } | ||||
| 
 | ||||
| int fileReadCallback(void) { | ||||
|   return file.read(); | ||||
| } | ||||
| 
 | ||||
| int fileReadBlockCallback(void * buffer, int numberOfBytes) { | ||||
|   return file.read((uint8_t*)buffer, numberOfBytes); | ||||
| } | ||||
| 
 | ||||
| int fileSizeCallback(void) { | ||||
|   return file.size(); | ||||
| } | ||||
| 
 | ||||
| bool openGif(const char *filename) { | ||||
|   file = WLED_FS.open(filename, "r"); | ||||
| 
 | ||||
|   if (!file) return false; | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| Segment* activeSeg; | ||||
| uint16_t gifWidth, gifHeight; | ||||
| 
 | ||||
| void screenClearCallback(void) { | ||||
|   activeSeg->fill(0); | ||||
| } | ||||
| 
 | ||||
| void updateScreenCallback(void) {} | ||||
| 
 | ||||
| void drawPixelCallback(int16_t x, int16_t y, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|   // simple nearest-neighbor scaling 
 | ||||
|   int16_t outY = y * activeSeg->height() / gifHeight; | ||||
|   int16_t outX = x * activeSeg->width()  / gifWidth; | ||||
|   // set multiple pixels if upscaling
 | ||||
|   for (int16_t i = 0; i < (activeSeg->width()+(gifWidth-1)) / gifWidth; i++) { | ||||
|     for (int16_t j = 0; j < (activeSeg->height()+(gifHeight-1)) / gifHeight; j++) { | ||||
|       activeSeg->setPixelColorXY(outX + i, outY + j, gamma8(red), gamma8(green), gamma8(blue)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #define IMAGE_ERROR_NONE 0 | ||||
| #define IMAGE_ERROR_NO_NAME 1 | ||||
| #define IMAGE_ERROR_SEG_LIMIT 2 | ||||
| #define IMAGE_ERROR_UNSUPPORTED_FORMAT 3 | ||||
| #define IMAGE_ERROR_FILE_MISSING 4 | ||||
| #define IMAGE_ERROR_DECODER_ALLOC 5 | ||||
| #define IMAGE_ERROR_GIF_DECODE 6 | ||||
| #define IMAGE_ERROR_FRAME_DECODE 7 | ||||
| #define IMAGE_ERROR_WAITING 254 | ||||
| #define IMAGE_ERROR_PREV 255 | ||||
| 
 | ||||
| // renders an image (.gif only; .bmp and .fseq to be added soon) from FS to a segment
 | ||||
| byte renderImageToSegment(Segment &seg) { | ||||
|   if (!seg.name) return IMAGE_ERROR_NO_NAME; | ||||
|   // disable during effect transition, causes flickering, multiple allocations and depending on image, part of old FX remaining
 | ||||
|   if (seg.mode != seg.currentMode()) return IMAGE_ERROR_WAITING; | ||||
|   if (activeSeg && activeSeg != &seg) return IMAGE_ERROR_SEG_LIMIT; // only one segment at a time
 | ||||
|   activeSeg = &seg; | ||||
| 
 | ||||
|   if (strncmp(lastFilename +1, seg.name, 32) != 0) { // segment name changed, load new image
 | ||||
|     strncpy(lastFilename +1, seg.name, 32); | ||||
|     gifDecodeFailed = false; | ||||
|     if (strcmp(lastFilename + strlen(lastFilename) - 4, ".gif") != 0) { | ||||
|       gifDecodeFailed = true; | ||||
|       return IMAGE_ERROR_UNSUPPORTED_FORMAT; | ||||
|     } | ||||
|     if (file) file.close(); | ||||
|     openGif(lastFilename); | ||||
|     if (!file) { gifDecodeFailed = true; return IMAGE_ERROR_FILE_MISSING; } | ||||
|     decoder.setScreenClearCallback(screenClearCallback); | ||||
|     decoder.setUpdateScreenCallback(updateScreenCallback); | ||||
|     decoder.setDrawPixelCallback(drawPixelCallback); | ||||
|     decoder.setFileSeekCallback(fileSeekCallback); | ||||
|     decoder.setFilePositionCallback(filePositionCallback); | ||||
|     decoder.setFileReadCallback(fileReadCallback); | ||||
|     decoder.setFileReadBlockCallback(fileReadBlockCallback); | ||||
|     decoder.setFileSizeCallback(fileSizeCallback); | ||||
|     decoder.alloc(); | ||||
|     DEBUG_PRINTLN(F("Starting decoding")); | ||||
|     if(decoder.startDecoding() < 0) { gifDecodeFailed = true; return IMAGE_ERROR_GIF_DECODE; } | ||||
|     DEBUG_PRINTLN(F("Decoding started")); | ||||
|   } | ||||
| 
 | ||||
|   if (gifDecodeFailed) return IMAGE_ERROR_PREV; | ||||
|   if (!file) { gifDecodeFailed = true; return IMAGE_ERROR_FILE_MISSING; } | ||||
|   //if (!decoder) { gifDecodeFailed = true; return IMAGE_ERROR_DECODER_ALLOC; }
 | ||||
| 
 | ||||
|   // speed 0 = half speed, 128 = normal, 255 = full FX FPS
 | ||||
|   // TODO: 0 = 4x slow, 64 = 2x slow, 128 = normal, 192 = 2x fast, 255 = 4x fast
 | ||||
|   uint32_t wait = currentFrameDelay * 2 - seg.speed * currentFrameDelay / 128; | ||||
| 
 | ||||
|   // TODO consider handling this on FX level with a different frametime, but that would cause slow gifs to speed up during transitions
 | ||||
|   if (millis() - lastFrameDisplayTime < wait) return IMAGE_ERROR_WAITING; | ||||
| 
 | ||||
|   decoder.getSize(&gifWidth, &gifHeight); | ||||
| 
 | ||||
|   int result = decoder.decodeFrame(false); | ||||
|   if (result < 0) { gifDecodeFailed = true; return IMAGE_ERROR_FRAME_DECODE; } | ||||
| 
 | ||||
|   currentFrameDelay = decoder.getFrameDelay_ms(); | ||||
|   unsigned long tooSlowBy = (millis() - lastFrameDisplayTime) - wait; // if last frame was longer than intended, compensate
 | ||||
|   currentFrameDelay = tooSlowBy > currentFrameDelay ? 0 : currentFrameDelay - tooSlowBy; | ||||
|   lastFrameDisplayTime = millis(); | ||||
| 
 | ||||
|   return IMAGE_ERROR_NONE; | ||||
| } | ||||
| 
 | ||||
| void endImagePlayback(Segment *seg) { | ||||
|   DEBUG_PRINTLN(F("Image playback end called")); | ||||
|   if (!activeSeg || activeSeg != seg) return; | ||||
|   if (file) file.close(); | ||||
|   decoder.dealloc(); | ||||
|   gifDecodeFailed = false; | ||||
|   activeSeg = nullptr; | ||||
|   lastFilename[1] = '\0'; | ||||
|   DEBUG_PRINTLN(F("Image playback ended")); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Will Tatam
						Will Tatam