A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 205 lines 7.5 kB view raw
1--[[ Lua Image functions 2/*************************************************************************** 3 * __________ __ ___. 4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 8 * \/ \/ \/ \/ \/ 9 * $Id$ 10 * 11 * Copyright (C) 2017 William Wilgus 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License 15 * as published by the Free Software Foundation; either version 2 16 * of the License, or (at your option) any later version. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ****************************************************************************/ 22]] 23 24--[[ Exposed Functions 25 26 _img.search 27 _img.rotate 28 _img.resize 29 _img.tile 30 _img.new 31 _img.load 32 33-- Exposed Constants 34 _img.RLI_INFO_ALL 35 _img.RLI_INFO_TYPE 36 _img.RLI_INFO_WIDTH 37 _img.RLI_INFO_HEIGHT 38 _img.RLI_INFO_ELEMS 39 _img.RLI_INFO_BYTES 40 _img.RLI_INFO_DEPTH 41 _img.RLI_INFO_FORMAT 42 _img.RLI_INFO_ADDRESS 43 44]] 45 46--[[Other rbimage Functions: 47-------------------------------------------------------------------------------- 48img:_len() or #img -- returns number of pixels in image 49 50img:__tostring([item]) or tostring(img) -- returns data about the image item = 0 51 is the same as tostring(img) otherwise 52 item = 1 is the first item in list 53 item = 7 is the 7th item 54 item = 8 is the data address in hex 55 -- See Constants _img.RLI_INFO_.... 56 57img:_data(element) -- returns/sets raw pixel data 58 NOTE!! this data is defined by the target and targets with 59 different color depth, bit packing, etc will not be 60 compatible with the same image's data on another target 61]] 62-------------------------------------------------------------------------------- 63if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end 64 65local _img = {} do 66 67 local rocklib_image = getmetatable(rb.lcd_framebuffer()) 68 setmetatable(_img, rocklib_image) 69 70 -- internal constants 71 local _NIL = nil -- _NIL placeholder 72 local _math = require("math_ex") -- math functions needed 73 local LCD_W, LCD_H = rb.LCD_WIDTH, rb.LCD_HEIGHT 74 75 local _copy = rocklib_image.copy 76 local _get = rocklib_image.get 77 local _marshal = rocklib_image.marshal 78 local _points = rocklib_image.points 79 80 -- returns new image -of- img sized to fit w/h tiling to fit if needed 81 _img.tile = function(img, w, h) 82 local hs , ws = img:height(), img:width() 83 local t_img = rb.new_image(w, h) 84 85 for x = 1, w, ws do _copy(t_img, img, x, 1, 1, 1) end 86 for y = hs, h, hs do _copy(t_img, t_img, 1, y, 1, 1, w, hs) end 87 return t_img 88 end 89 90 -- resizes src to size of dst 91 _img.resize = function(dst, src) 92 -- simple nearest neighbor resize derived from rockbox - pluginlib_bmp.c 93 -- pretty rough results highly recommend building one more suited.. 94 local dw, dh = dst:width(), dst:height() 95 96 local xstep = (bit.lshift(src:width(), 8) / (dw)) + 1 97 local ystep = (bit.lshift(src:height(), 8) / (dh)) 98 99 local xpos, ypos = 0, 0 100 local src_x, src_y 101 102 -- walk the dest get src pixel 103 local function rsz_trans(val, x, y) 104 if x == 1 then 105 src_y = bit.rshift(ypos,8) + 1 106 xpos = xstep - bit.rshift(xstep,4) + 1 107 ypos = ypos + ystep; 108 end 109 src_x = bit.rshift(xpos,8) + 1 110 xpos = xpos + xstep 111 return (_get(src, src_x, src_y, true) or 0) 112 end 113 --/* (dst*, [x1, y1, x2, y2, dx, dy, clip, function]) */ 114 _marshal(dst, 1, 1, dw, dh, _NIL, _NIL, false, rsz_trans) 115 end 116 117 -- returns new image -of- img rotated in whole degrees 0 - 360 118 _img.rotate = function(img, degrees) 119 -- we do this backwards as if dest was the unrotated object 120 degrees = 360 - degrees 121 local c, s = _math.d_cos(degrees), _math.d_sin(degrees) 122 123 -- get the center of the source image 124 local s_xctr, s_yctr = img:width() / 2, img:height() / 2 125 126 -- get the the new center of the dest image at rotation angle 127 local d_xctr = ((math.abs(s_xctr * c) + math.abs(s_yctr * s))/ 10000) + 1 128 local d_yctr = ((math.abs(s_xctr * s) + math.abs(s_yctr * c))/ 10000) + 1 129 130 -- calculate size of rect new image will occupy 131 local dw, dh = d_xctr * 2 - 1, d_yctr * 2 - 1 132 133 local r_img = rb.new_image(dw, dh) 134 -- r_img:clear() -- doesn't need cleared as we walk every pixel 135 136 --[[rotation works on origin of 0,0 we need to offset to the center of the 137 image and then place the upper left back at the origin (0, 0)]] 138 --[[0,0|-----| ^< |-------| v> 0,0|-------| 139 | | | 0,0 | | | 140 |_____| |_______| |_______| ]] 141 142 -- walk the dest get translated src pixel, oversamples src to fill gaps 143 local function rot_trans(val, x, y) 144 -- move center x/y to the origin 145 local xtran = x - d_xctr; 146 local ytran = y - d_yctr; 147 148 -- rotate about the center of the image by x degrees 149 local yrot = ((xtran * s) + (ytran * c)) / 10000 + s_yctr 150 local xrot = ((xtran * c) - (ytran * s)) / 10000 + s_xctr 151 -- upper left of src image back to origin, copy src pixel 152 return _get(img, xrot, yrot, true) or 0 153 end 154 _marshal(r_img, 1, 1, dw, dh, _NIL, _NIL, false, rot_trans) 155 return r_img 156 end 157 158 --searches an image for target color 159 _img.search = function(img, x1, y1, x2, y2, targetclr, variation, stepx, stepy) 160 161 if variation > 128 then variation = 128 end 162 if variation < -128 then variation = -128 end 163 164 local targeth = targetclr + variation 165 local targetl = targetclr - variation 166 167 if targeth < targetl then 168 local swap = targeth 169 targeth = targetl 170 targetl = swap 171 end 172 173 for point, x, y in _points(img, x1, y1, x2, y2, stepx, stepy) do 174 if point >= targetl and point <= targeth then 175 return point, x, y 176 end 177 end 178 return nil, nil, nil 179 end 180 181 --[[ we won't be extending these into RLI_IMAGE]] 182 -- creates a new rbimage size w x h 183 _img.new = function(w, h) 184 return rb.new_image(w, h) 185 end 186 187 -- returns new image -of- file: name (_NIL if error) 188 _img.load = function(name) 189 return rb.read_bmp_file("/" .. name) 190 end 191 192 -- expose tostring constants to outside through _img table 193 _img.RLI_INFO_ALL = 0x0 194 _img.RLI_INFO_TYPE = 0x1 195 _img.RLI_INFO_WIDTH = 0x2 196 _img.RLI_INFO_HEIGHT = 0x3 197 _img.RLI_INFO_ELEMS = 0x4 198 _img.RLI_INFO_BYTES = 0x5 199 _img.RLI_INFO_DEPTH = 0x6 200 _img.RLI_INFO_FORMAT = 0x7 201 _img.RLI_INFO_ADDRESS = 0x8 202end -- _img functions 203 204return _img 205