diff --git a/platformio.ini b/platformio.ini index 66bd09957..73d82c3a7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -221,7 +221,7 @@ lib_deps = https://github.com/lorol/LITTLEFS.git https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 bitbank2/AnimatedGIF@^1.4.7 - pixelmatix/GifDecoder@^1.1.0 + https://github.com/Aircoookie/GifDecoder#e76f58f ${env.lib_deps} # additional build flags for audioreactive AR_build_flags = -D USERMOD_AUDIOREACTIVE diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 681f3d107..e8c59babe 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -4470,7 +4470,12 @@ static const char _data_FX_MODE_WASHING_MACHINE[] PROGMEM = "Washing Machine@!,! Draws a .gif image from filesystem on the matrix/strip */ uint16_t mode_image(void) { - renderImageToSegment(SEGMENT); + //Serial.println(renderImageToSegment(SEGMENT)); + int status = renderImageToSegment(SEGMENT); + if (status != 0 && status != 254 && status != 255) { + Serial.print("GIF renderer return: "); + Serial.println(status); + } return FRAMETIME; } static const char _data_FX_MODE_IMAGE[] PROGMEM = "Image@!,;;;12;sx=128"; @@ -7973,7 +7978,7 @@ 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); - + addEffect(FX_MODE_IMAGE, &mode_image, _data_FX_MODE_IMAGE); 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); @@ -8035,8 +8040,6 @@ void WS2812FX::setupEffectData() { addEffect(FX_MODE_DANCING_SHADOWS, &mode_dancing_shadows, _data_FX_MODE_DANCING_SHADOWS); addEffect(FX_MODE_WASHING_MACHINE, &mode_washing_machine, _data_FX_MODE_WASHING_MACHINE); - addEffect(FX_MODE_IMAGE, &mode_image, _data_FX_MODE_IMAGE); - addEffect(FX_MODE_BLENDS, &mode_blends, _data_FX_MODE_BLENDS); addEffect(FX_MODE_TV_SIMULATOR, &mode_tv_simulator, _data_FX_MODE_TV_SIMULATOR); addEffect(FX_MODE_DYNAMIC_SMOOTH, &mode_dynamic_smooth, _data_FX_MODE_DYNAMIC_SMOOTH); diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 42e98452f..94fdb3006 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -199,6 +199,7 @@ 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; + endImagePlayback(this); } CRGBPalette16 IRAM_ATTR &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 72918d1a2..4619e640a 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -136,6 +136,7 @@ int fileReadCallback(void); int fileReadBlockCallback(void * buffer, int numberOfBytes); int fileSizeCallback(void); byte renderImageToSegment(Segment &seg); +void endImagePlayback(Segment* seg); #endif //improv.cpp diff --git a/wled00/image_loader.cpp b/wled00/image_loader.cpp index 4a8052400..44fb7f7c8 100644 --- a/wled00/image_loader.cpp +++ b/wled00/image_loader.cpp @@ -5,7 +5,7 @@ File file; char lastFilename[34] = "/"; -GifDecoder<32,32,12> decoder; +GifDecoder<32,32,12,true> decoder; bool gifDecodeFailed = false; long lastFrameDisplayTime = 0, currentFrameDelay = 0; @@ -85,7 +85,7 @@ byte renderImageToSegment(Segment &seg) { if (file) file.close(); openGif(lastFilename); if (!file) { gifDecodeFailed = true; return IMAGE_ERROR_FILE_MISSING; } - //if (!decoder) decoder = new GifDecoder<32,32,12>(); + //if (!decoder) decoder = new GifDecoder<32,32,12,true>(); //if (!decoder) { gifDecodeFailed = true; return IMAGE_ERROR_DECODER_ALLOC; } decoder.setScreenClearCallback(screenClearCallback); decoder.setUpdateScreenCallback(updateScreenCallback); @@ -95,6 +95,7 @@ byte renderImageToSegment(Segment &seg) { decoder.setFileReadCallback(fileReadCallback); decoder.setFileReadBlockCallback(fileReadBlockCallback); decoder.setFileSizeCallback(fileSizeCallback); + decoder.alloc(); // TODO only if not already allocated Serial.println("Starting decoding"); if(decoder.startDecoding() < 0) { gifDecodeFailed = true; return IMAGE_ERROR_GIF_DECODE; } Serial.println("Decoding started"); @@ -124,12 +125,16 @@ byte renderImageToSegment(Segment &seg) { return IMAGE_ERROR_NONE; } -void endImagePlayback() { +void endImagePlayback(Segment *seg) { + Serial.println("Image playback end called"); + if (!activeSeg || activeSeg != seg) return; if (file) file.close(); //delete decoder; + decoder.dealloc(); gifDecodeFailed = false; activeSeg = nullptr; - lastFilename[0] = '\0'; + lastFilename[1] = '\0'; + Serial.println("Image playback ended"); } #endif \ No newline at end of file