[Bugfix] FS#13878 FS#13862 lua alpha bmp overflow and image flip example

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Wed, 29 Apr 2026 02:21:45 -0400
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 1068433d5b3ed4a7df75b266e547f6956c75c16e
Author: William Wilgus <[email protected]>
Date:   Wed Apr 29 01:53:02 2026 -0400

    [Bugfix] FS#13878 FS#13862 lua alpha bmp overflow and image flip example
    
    FS#13878 - 292x216 images cause panic
     alpha channel causes overflow
    
    FS#13862 - In rlimg example "flip image" cause error
     missing local variable
    
    save random and rainbow images
    
    fix ball bounce direction
    
    Change-Id: I717eb029f30bf63d2eef0b7997eb04036ffeda15

diff --git a/apps/plugins/lua/rocklib_img.c b/apps/plugins/lua/rocklib_img.c
index c58a5b6681..df5e028283 100644
--- a/apps/plugins/lua/rocklib_img.c
+++ b/apps/plugins/lua/rocklib_img.c
@@ -349,7 +349,7 @@ static struct rocklua_image* rli_checktype(lua_State *L, int arg)
 } /* rli_checktype */
 
 static struct rocklua_image * alloc_rlimage(lua_State *L, bool alloc_data,
-                                            int width, int height)
+                                            int width, int height, size_t *allocd)
 {
     /* rliimage is pushed on the stack it is up to you to pop it */
     struct rocklua_image *img;
@@ -365,10 +365,24 @@ static struct rocklua_image * alloc_rlimage(lua_State *L, bool alloc_data,
 
     n_elems = (size_t)(w_native * h_native);
 
-    if(alloc_data) /* if this a new image we need space for image data */
-        sz_data = n_elems * sizeof(fb_data);
+    if(alloc_data)
+    {/* if this a new image we need space for image data */
+    /* need even rows (see lcd-16bit-common.c for details) */
+        sz_data = BM_SIZE(width,height,FORMAT_NATIVE,false);
+#if LCD_DEPTH > 24 /* account for possible 4bit alpha per pixel */
+        sz_data += ALIGN_UP(width, 2) * height / 2;
+#endif
 
+#if (LCD_DEPTH > 1) && defined(HAVE_BMP_SCALING)
+        if (width > BM_MAX_WIDTH)
+            sz_data += width*4;
+#endif
+        sz_data = MAX(n_elems * sizeof(fb_data), sz_data);
+    }
+    if (allocd)
+        *allocd = sz_data;
     /* newuserdata pushes the userdata onto the stack */
+    /*DEBUGF("rli alloc %d\n", sz_header + sz_data);*/
     img = (struct rocklua_image *) lua_newuserdata(L, sz_header + sz_data);
 
     luaL_getmetatable(L, ROCKLUA_IMAGE);
@@ -386,15 +400,15 @@ static struct rocklua_image * alloc_rlimage(lua_State *L, bool alloc_data,
 static inline void rli_wrap(lua_State *L, fb_data *src, int width, int height)
 {
     /* rliimage is pushed on the stack it is up to you to pop it */
-    struct rocklua_image *a = alloc_rlimage(L, false, width, height);
+    struct rocklua_image *a = alloc_rlimage(L, false, width, height, NULL);
 
     a->data = src;
 } /* rli_wrap */
 
-static inline fb_data* rli_alloc(lua_State *L, int width, int height)
+static inline fb_data* rli_alloc(lua_State *L, int width, int height, size_t *allocd)
 {
     /* rliimage is pushed on the stack it is up to you to pop it */
-    struct rocklua_image *a = alloc_rlimage(L, true, width, height);
+    struct rocklua_image *a = alloc_rlimage(L, true, width, height, allocd);
 
     a->data = &a->dummy[0][0]; /* ref to beginning of alloc'd img data */
 
@@ -995,7 +1009,7 @@ RLI_LUA rli_new(lua_State *L)
 
     luaL_argcheck(L, width > 0 && height > 0, (width <= 0) ? 1 : 2, ERR_IDX_RANGE);
 
-    rli_alloc(L, width, height);
+    rli_alloc(L, width, height, NULL);
 
     return 1;
 }
@@ -1904,10 +1918,13 @@ RB_WRAP(read_bmp_file)
 
     int result = rb->read_bmp_file(filename, &bm, 0, format | FORMAT_RETURN_SIZE, NULL);
 
+    /*DEBUGF("read_bmp wants %d %d\n", result, BM_SIZE(bm.width, bm.height, format, false));*/
+
     if(result > 0)
     {
-        bm.data = (unsigned char*) rli_alloc(L, bm.width, bm.height);
-        if(rb->read_bmp_file(filename, &bm, result, format, NULL) < 0)
+        size_t sz_data;
+        bm.data = (unsigned char*) rli_alloc(L, bm.width, bm.height, &sz_data);
+        if(rb->read_bmp_file(filename, &bm, sz_data, format, NULL) < 0)
         {
             /* Error occured, drop newly allocated image from stack */
             lua_pop(L, 1);
diff --git a/apps/plugins/lua_scripts/rlimg.lua b/apps/plugins/lua_scripts/rlimg.lua
index b3fa72426c..7299f4e207 100755
--- a/apps/plugins/lua_scripts/rlimg.lua
+++ b/apps/plugins/lua_scripts/rlimg.lua
@@ -274,11 +274,11 @@ function bounce_image(img)
 
         if IS_COLOR_TARGET then
             if bit.band(loops, 128) == 128 then
-                _lcd:copy(imgn, x, y, 1, 1, fx, fy, false, _blit.BOR)
+                _lcd:copy(imgn, x, y, 1, 1, -fx, -fy, false, _blit.BOR)
                 _lcd:copy(screen_img, x, y, x, y, imgn:width(), imgn:height(),
                                          false, _blit.BDEQC, imgn:get(1,1))
             else
-                _lcd:copy(imgn, x, y, 1, 1, fx, fy, false, _blit.BSNEC, imgn:get(1,1))
+                _lcd:copy(imgn, x, y, 1, 1, -fx, -fy, false, _blit.BSNEC, imgn:get(1,1))
             end
         else
             local blitop
@@ -289,7 +289,7 @@ function bounce_image(img)
                 blitop = _blit.BXOR
             end
 
-            _lcd:copy(imgn, x, y, 1, 1, fx, fy, false, blitop, WHITE)
+            _lcd:copy(imgn, x, y, 1, 1, -fx, -fy, false, blitop, WHITE)
         end
 
         if hold < 1 then
@@ -674,6 +674,7 @@ end -- rotate_image
 
 function flip_image(img)
     local blitop = _blit.BOR
+    local i = 1
     local d = 0
     local x, y, w, h
 
@@ -689,7 +690,7 @@ function flip_image(img)
     --[[--Profiling code
     local timer = _timer.start()]]
 
-    while d >= 0 do
+    while d >= 0 and img do
         -- copy our flipped image onto the background
         if d == 0 then
             _lcd:copy(img, x, y, 1, 1, w, h, false, blitop)
@@ -757,7 +758,7 @@ end -- draw_x
 function random_img(img)
     local min = _clr.set(0, 0, 0, 0)
     local max = _clr.set(-1, 255, 255, 255)
-    math.randomseed(rb.current_tick())
+    --math.randomseed(rb.current_tick())
     for x = 1, img:width() do
         for y = 1, img:height() do
             img:set(x, y, math.random(min, max))
@@ -896,9 +897,13 @@ function main_menu()
                 [10]  = long_text,
                 [11] = function(RAINB)
                          rainbow_img(_lcd()); _lcd:update(); rb.sleep(rb.HZ)
+                         if rb.file_exists == nil or not rb.file_exists("/rainbow.bmp") then
+                            _img_save(_LCD, "/rainbow.bmp")
+                         end
                        end,
                 [12] = function(RANDM)
                          random_img(_lcd()); _lcd:update(); rb.sleep(rb.HZ)
+                         _img_save(_LCD, "/random.bmp")
                        end,
                 [13] = function(CLEAR) _lcd:clear(BLACK); rock_lua() end,
                 [14] = function(SAVEI) _LCD:invert(); _img_save(_LCD, "/rocklua.bmp") end,
@@ -927,6 +932,8 @@ _timer("main") -- keep track of how long the program ran
 -- Clear the screen
 _lcd:clear(BLACK)
 
+math.randomseed(rb.current_tick())
+
 if LCD_DEPTH > 1 then
 --draw a gradient using available colors
 if IS_COLOR_TARGET == true then
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs