A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
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