Добавил фичи чтения метаданных картинок, не дожидаясь их полной загрузки в оперативу

This commit is contained in:
IgorTimofeev 2022-07-09 18:22:57 +03:00
parent 86855ed96f
commit cfa60a90cb
2 changed files with 137 additions and 52 deletions

View File

@ -7,8 +7,9 @@ local filesystem = require("Filesystem")
local image = {} local image = {}
local OCIFSignature = "OCIF" local OCIFSignature = "OCIF"
local encodingMethodsLoad = {} local encodingMethodsRead = {}
local encodingMethodsSave = {} local encodingMethodsReadMetadata = {}
local encodingMethodsWrite = {}
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -44,7 +45,8 @@ local function group(picture, compressColors)
return groupedPicture return groupedPicture
end end
encodingMethodsSave[5] = function(file, picture) -- 5
encodingMethodsWrite[5] = function(file, picture)
file:writeBytes( file:writeBytes(
bit32.rshift(picture[1], 8), bit32.rshift(picture[1], 8),
bit32.band(picture[1], 0xFF) bit32.band(picture[1], 0xFF)
@ -66,11 +68,17 @@ encodingMethodsSave[5] = function(file, picture)
end end
end end
encodingMethodsLoad[5] = function(file, picture) encodingMethodsReadMetadata[5] = function(file)
picture[1] = file:readBytes(2) return
picture[2] = file:readBytes(2) file:readBytes(2),
file:readBytes(2)
end
for i = 1, image.getWidth(picture) * image.getHeight(picture) do encodingMethodsRead[5] = function(file, picture, width, height)
picture[1] = width
picture[2] = height
for i = 1, width * height do
table.insert(picture, color.to24Bit(file:readBytes(1))) table.insert(picture, color.to24Bit(file:readBytes(1)))
table.insert(picture, color.to24Bit(file:readBytes(1))) table.insert(picture, color.to24Bit(file:readBytes(1)))
table.insert(picture, file:readBytes(1) / 255) table.insert(picture, file:readBytes(1) / 255)
@ -78,9 +86,15 @@ encodingMethodsLoad[5] = function(file, picture)
end end
end end
local function loadOCIF678(file, picture, is7, is8) local function readMetadata678(file, is7, is8)
picture[1] = file:readBytes(1) + is8 return
picture[2] = file:readBytes(1) + is8 file:readBytes(1) + is8,
file:readBytes(1) + is8
end
local function read678(file, picture, width, height, is7, is8)
picture[1] = width
picture[2] = height
local currentAlpha, currentSymbol, currentBackground, currentForeground, currentY local currentAlpha, currentSymbol, currentBackground, currentForeground, currentY
@ -194,30 +208,45 @@ local function saveOCIF678(file, picture, is7, is8)
end end
end end
encodingMethodsSave[6] = function(file, picture) -- 6
encodingMethodsReadMetadata[6] = function(file)
return readMetadata678(file, 0, 0)
end
encodingMethodsRead[6] = function(file, picture, width, height)
read678(file, picture, width, height, 0, 0)
end
encodingMethodsWrite[6] = function(file, picture)
saveOCIF678(file, picture, 0, 0) saveOCIF678(file, picture, 0, 0)
end end
encodingMethodsLoad[6] = function(file, picture) -- 7
loadOCIF678(file, picture, 0, 0) encodingMethodsReadMetadata[7] = function(file)
return readMetadata678(file, 1, 0)
end end
encodingMethodsSave[7] = function(file, picture) encodingMethodsRead[7] = function(file, picture, width, height)
read678(file, picture, width, height, 1, 0)
end
encodingMethodsWrite[7] = function(file, picture)
saveOCIF678(file, picture, 1, 0) saveOCIF678(file, picture, 1, 0)
end end
encodingMethodsLoad[7] = function(file, picture) -- 8
loadOCIF678(file, picture, 1, 0) encodingMethodsReadMetadata[8] = function(file)
return readMetadata678(file, 1, 1)
end end
encodingMethodsSave[8] = function(file, picture) encodingMethodsRead[8] = function(file, picture, width, height)
read678(file, picture, width, height, 1, 1)
end
encodingMethodsWrite[8] = function(file, picture)
saveOCIF678(file, picture, 1, 1) saveOCIF678(file, picture, 1, 1)
end end
encodingMethodsLoad[8] = function(file, picture)
loadOCIF678(file, picture, 1, 1)
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function image.getIndex(x, y, width) function image.getIndex(x, y, width)
@ -251,11 +280,12 @@ function image.save(path, picture, encodingMethod)
encodingMethod = encodingMethod or 6 encodingMethod = encodingMethod or 6
local file, reason = filesystem.open(path, "wb") local file, reason = filesystem.open(path, "wb")
if file then if file then
if encodingMethodsSave[encodingMethod] then if encodingMethodsWrite[encodingMethod] then
file:write(OCIFSignature, string.char(encodingMethod)) file:write(OCIFSignature, string.char(encodingMethod))
local result, reason = xpcall(encodingMethodsSave[encodingMethod], debug.traceback, file, picture) local result, reason = xpcall(encodingMethodsWrite[encodingMethod], debug.traceback, file, picture)
file:close() file:close()
@ -266,6 +296,7 @@ function image.save(path, picture, encodingMethod)
end end
else else
file:close() file:close()
return false, "Failed to save OCIF image: encoding method \"" .. tostring(encodingMethod) .. "\" is not supported" return false, "Failed to save OCIF image: encoding method \"" .. tostring(encodingMethod) .. "\" is not supported"
end end
else else
@ -273,30 +304,56 @@ function image.save(path, picture, encodingMethod)
end end
end end
function image.load(path) function image.readMetadata(file)
local file, reason = filesystem.open(path, "rb") local signature = file:readString(#OCIFSignature)
if file then
local readedSignature = file:readString(#OCIFSignature) if signature == OCIFSignature then
if readedSignature == OCIFSignature then local encodingMethod = file:readBytes(1)
local encodingMethod = file:readBytes(1)
if encodingMethodsLoad[encodingMethod] then if encodingMethodsReadMetadata[encodingMethod] then
local picture = {} local result, widthOrReason, height = xpcall(encodingMethodsReadMetadata[encodingMethod], debug.traceback, file, picture)
local result, reason = xpcall(encodingMethodsLoad[encodingMethod], debug.traceback, file, picture)
if result then
file:close() return signature, encodingMethod, widthOrReason, height
if result then
return picture
else
return false, "Failed to load OCIF image: " .. tostring(reason)
end
else else
file:close() file:close()
return false, "Failed to load OCIF image: encoding method \"" .. tostring(encodingMethod) .. "\" is not supported"
return false, "Failed to read OCIF metadata: " .. tostring(widthOrReason)
end end
else else
file:close() file:close()
return false, "Failed to load OCIF image: binary signature \"" .. tostring(readedSignature) .. "\" is not valid"
return false, "Failed to read OCIF metadata: encoding method \"" .. tostring(encodingMethod) .. "\" is not supported"
end
else
file:close()
return false, "Failed to read OCIF metadata: binary signature \"" .. tostring(signature) .. "\" is not valid"
end
end
function image.readPixelData(file, encodingMethod, width, height)
local picture = {}
local result, reason = xpcall(encodingMethodsRead[encodingMethod], debug.traceback, file, picture, width, height)
file:close()
if result then
return picture
else
return false, "Failed to read OCIF pixel data: " .. tostring(reason)
end
end
function image.load(path)
local file, reason = filesystem.open(path, "rb")
if file then
local signature, encodingMethod, width, height = image.readMetadata(file)
if signature then
return image.readPixelData(file, encodingMethod, width, height)
else
return false, encodingMethod
end end
else else
return false, "Failed to open file \"" .. tostring(path) .. "\" for reading: " .. tostring(reason) return false, "Failed to open file \"" .. tostring(path) .. "\" for reading: " .. tostring(reason)

View File

@ -974,29 +974,57 @@ local function anyIconAnalyseExtension(icon, launchers)
icon.image = shortcutIcon.image icon.image = shortcutIcon.image
icon.shortcutLaunch = shortcutIcon.launch icon.shortcutLaunch = shortcutIcon.launch
icon.launch = launchers.shortcut icon.launch = launchers.shortcut
elseif icon.extension == ".pkg" then elseif icon.extension == ".pkg" then
icon.image = iconCache.archive icon.image = iconCache.archive
icon.launch = launchers.archive icon.launch = launchers.archive
elseif userSettings.extensions[icon.extension] then elseif userSettings.extensions[icon.extension] then
if iconCache[icon.extension] then icon.launch = launchers.extension
icon.image = iconCache[icon.extension]
local picture
if icon.extension == ".pic" then
local file = filesystem.open(icon.path, "rb")
if file then
local signature, encodingMethod, width, height = image.readMetadata(file)
if signature and width <= 8 and height <= 4 then
picture = image.readPixelData(file, encodingMethod, width, height)
if picture then
icon.image = picture
return icon
end
end
end
else else
local picture = picture = iconCache[icon.extension]
image.load(userSettings.extensions[icon.extension] .. "Extensions/" .. icon.extension .. "/Icon.pic") or
image.load(userSettings.extensions[icon.extension] .. "Icon.pic")
if picture then if picture then
iconCache[icon.extension] = picture
icon.image = picture icon.image = picture
else
icon.image = iconCache.fileNotExists return icon
end end
end end
icon.launch = launchers.extension picture =
image.load(userSettings.extensions[icon.extension] .. "Extensions/" .. icon.extension .. "/Icon.pic") or
image.load(userSettings.extensions[icon.extension] .. "Icon.pic")
if picture then
iconCache[icon.extension] = picture
icon.image = picture
else
icon.image = iconCache.fileNotExists
end
elseif not filesystem.exists(icon.path) then elseif not filesystem.exists(icon.path) then
icon.image = iconCache.fileNotExists icon.image = iconCache.fileNotExists
icon.launch = launchers.corrupted icon.launch = launchers.corrupted
else else
icon.image = iconCache.script icon.image = iconCache.script
icon.launch = launchers.script icon.launch = launchers.script