(experimental) adjust image scaling when segment options change during playback
* move scaling calculation and decoder.setDrawPixelCallback() into a separate function *re-calculate scaling before decoding a new frame * reset gifWidth and gifHeight to zero in endplayback
This commit is contained in:
@@ -49,7 +49,7 @@ bool openGif(const char *filename) { // side-effect: updates "file"
|
||||
}
|
||||
|
||||
static Segment* activeSeg;
|
||||
static uint16_t gifWidth, gifHeight; // these two must stay uint16_t, because they are passed by reference
|
||||
static uint16_t gifWidth = 0, gifHeight = 0; // these two must stay uint16_t, because they are passed by reference
|
||||
static unsigned segCols = 1;
|
||||
static unsigned segRows = 1;
|
||||
static unsigned segLen = 1; // for 1D and 1DExpand support
|
||||
@@ -107,6 +107,29 @@ void drawPixelCallback2D(int16_t x, int16_t y, uint8_t red, uint8_t green, uint8
|
||||
}
|
||||
}
|
||||
|
||||
// calculate image scaling; updates scaling factors and sets the best pixel drawing callback
|
||||
static void calculateScaling() {
|
||||
if (gifDecodeFailed) return;
|
||||
if ((gifWidth > 0 && gifHeight > 0)) {
|
||||
if (activeSeg->is2D()) {
|
||||
perPixelX = (segCols + gifWidth -1) / gifWidth;
|
||||
perPixelY = (segRows + gifHeight-1) / gifHeight;
|
||||
if (segCols != gifWidth || segRows != gifHeight) {
|
||||
decoder.setDrawPixelCallback(drawPixelCallback2D); // use 2D callback with scaling
|
||||
} else {
|
||||
decoder.setDrawPixelCallback(drawPixelCallbackNoScale2D); // use 2D callback without scaling
|
||||
}
|
||||
} else {
|
||||
int totalImgPix = (int)gifWidth * gifHeight;
|
||||
if (totalImgPix - segLen == 1) totalImgPix--; // handle off-by-one: skip last pixel instead of first (gifs constructed from 1D input pad last pixel if length is odd)
|
||||
perPixelX = (segLen + totalImgPix-1) / totalImgPix;
|
||||
if (totalImgPix != segLen) {
|
||||
decoder.setDrawPixelCallback(drawPixelCallback1D); // use 1D callback with scaling
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define IMAGE_ERROR_NONE 0
|
||||
#define IMAGE_ERROR_NO_NAME 1
|
||||
#define IMAGE_ERROR_SEG_LIMIT 2
|
||||
@@ -192,24 +215,7 @@ byte renderImageToSegment(Segment &seg) {
|
||||
USER_PRINTF("Invalid GIF dimensions: %dx%d\n", gifWidth, gifHeight);
|
||||
return IMAGE_ERROR_GIF_DECODE;
|
||||
}
|
||||
if (activeSeg->is2D()) {
|
||||
perPixelX = (segCols + gifWidth -1) / gifWidth;
|
||||
perPixelY = (segRows + gifHeight-1) / gifHeight;
|
||||
if (segCols != gifWidth || segRows != gifHeight) {
|
||||
decoder.setDrawPixelCallback(drawPixelCallback2D); // use 2D callback with scaling
|
||||
//DEBUG_PRINTLN(F("scaling image"));
|
||||
} else {
|
||||
decoder.setDrawPixelCallback(drawPixelCallbackNoScale2D); // use 2D callback without scaling
|
||||
}
|
||||
} else {
|
||||
int totalImgPix = (int)gifWidth * gifHeight;
|
||||
if (totalImgPix - segLen == 1) totalImgPix--; // handle off-by-one: skip last pixel instead of first (gifs constructed from 1D input pad last pixel if length is odd)
|
||||
perPixelX = (segLen + totalImgPix-1) / totalImgPix;
|
||||
if (totalImgPix != segLen) {
|
||||
decoder.setDrawPixelCallback(drawPixelCallback1D); // use 1D callback with scaling
|
||||
//DEBUG_PRINTLN(F("scaling image"));
|
||||
}
|
||||
}
|
||||
calculateScaling();
|
||||
}
|
||||
|
||||
if (gifDecodeFailed) return IMAGE_ERROR_PREV;
|
||||
@@ -227,6 +233,9 @@ byte renderImageToSegment(Segment &seg) {
|
||||
unsigned td0 = millis();
|
||||
while (strip.isUpdating() && (millis() - td0 < 20)) delay(1); // wait up to 20ms for LED output to finish
|
||||
|
||||
// WLEDMM experimental: segment options might change (mirror, transpose, grouping, spacing) at any time
|
||||
calculateScaling(); // --> re-calculate scaling for each frame
|
||||
|
||||
int result = decoder.decodeFrame(false);
|
||||
if (result < 0) {
|
||||
USER_PRINTF("GIF Decoding error %d in decodeFrame().\n", result);
|
||||
@@ -247,6 +256,7 @@ void endImagePlayback(Segment *seg) {
|
||||
if (!activeSeg || activeSeg != seg) return;
|
||||
if (file) file.close();
|
||||
decoder.dealloc();
|
||||
gifWidth = 0; gifHeight = 0; // WLEDMM clear cached image dimensions
|
||||
gifDecodeFailed = false;
|
||||
activeSeg = nullptr;
|
||||
strcpy(lastFilename, "/"); // reset filename
|
||||
|
||||
Reference in New Issue
Block a user