Skip to content

Commit

Permalink
feat: only attempt to render a fixed list of image formats
Browse files Browse the repository at this point in the history
  • Loading branch information
3rd committed Nov 14, 2023
1 parent 11c7e62 commit 4c1c903
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 11 deletions.
13 changes: 10 additions & 3 deletions lua/image/image.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local utils = require("image/utils")
local renderer = require("image/renderer")
local magick = require("image/magick")
local renderer = require("image/renderer")
local utils = require("image/utils")

-- { ["buf:row"]: { id, height } }
---@type table<string, { id: number, height: number }>
Expand Down Expand Up @@ -202,7 +202,7 @@ end
---@param path string
---@param options? ImageOptions
---@param state State
---@return Image
---@return Image|nil
local from_file = function(path, options, state)
local opts = options or {}

Expand All @@ -214,6 +214,12 @@ local from_file = function(path, options, state)
local absolute_path = vim.fn.fnamemodify(path, ":p")
if not vim.loop.fs_stat(absolute_path) then utils.throw(("image.nvim: file not found: %s"):format(absolute_path)) end

-- bail if not an image
if not utils.magic.is_image(absolute_path) then
utils.debug(("image.nvim: not an image: %s"):format(absolute_path))
return nil
end

-- bypass magick processing if already processed
for _, instance in pairs(state.images) do
if instance.original_path == absolute_path then
Expand Down Expand Up @@ -332,6 +338,7 @@ local from_url = function(url, options, callback, state)
code = code,
signal = signal,
})
callback(nil)
end
end)

Expand Down
10 changes: 7 additions & 3 deletions lua/image/init.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local utils = require("image/utils")
local image = require("image/image")
local magick = require("image/magick")
local utils = require("image/utils")

---@type Options
local default_options = {
Expand Down Expand Up @@ -290,6 +290,7 @@ end
---@param win number? if nil or 0, uses current window
---@param buf number? if nil or 0, uses current buffer
---@param options ImageOptions?
---@return Image|nil
api.hijack_buffer = function(path, win, buf, options)
if not win or win == 0 then win = vim.api.nvim_get_current_win() end
if not buf or buf == 0 then buf = vim.api.nvim_get_current_buf() end
Expand All @@ -313,9 +314,12 @@ api.hijack_buffer = function(path, win, buf, options)
opts.buffer = buf

local img = api.from_file(path, opts)
img:render()

state.hijacked_win_buf_images[key] = img
if img then
img:render()
state.hijacked_win_buf_images[key] = img
end

return img
end

Expand Down
2 changes: 1 addition & 1 deletion lua/image/utils/document.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ local create_document_integration = function(config)
buffer = item.window.buffer,
with_virtual_padding = true,
})
if ok then render_image(image) end
if ok and image then render_image(image) end
end
end
end
Expand Down
8 changes: 5 additions & 3 deletions lua/image/utils/init.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
local base64 = require("image/utils/base64")
local logger = require("image/utils/logger")
local random = require("image/utils/random")
local window = require("image/utils/window")
local term = require("image/utils/term")
local magic = require("image/utils/magic")
local math = require("image/utils/math")
local offsets = require("image/utils/offsets")
local random = require("image/utils/random")
local term = require("image/utils/term")
local tmux = require("image/utils/tmux")
local window = require("image/utils/window")

return {
log = logger.log,
Expand All @@ -18,4 +19,5 @@ return {
math = math,
offsets = offsets,
tmux = tmux,
magic = magic,
}
45 changes: 45 additions & 0 deletions lua/image/utils/magic.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
-- local log = require("image/utils/logger")

local max_bytes = 9

local sigs = {
"\x89\x50\x4E\x47", -- PNG
"\xFF\xD8\xFF\xE0", -- JPEG
"\x52\x49\x46\x46", -- WEBP
"\x47\x49\x46\x38", -- GIF87a, GIF89a
"\x42\x4D", -- BMP
"\x66\x74\x79\x70", -- HEIC
"\x2F\x2A\x20\x58\x50\x4D\x20\x2A\x2F", -- XPM
"\x00\x00\x01\x00", -- ICO
}

---@param path string
---@param n? number
local get_header = function(path, n)
local f = assert(io.open(path, "rb"))
local bytes = { f:read(n):byte(1, n) }
f:close()
return bytes
end

local is_image = function(path)
local header_bytes = get_header(path, max_bytes)
-- local header_str = string.char(unpack(header_bytes))
-- log.debug("signature", header_str)

for _, sig in ipairs(sigs) do
local match = true
for i = 1, #sig do
if header_bytes[i] ~= string.byte(sig, i) then
match = false
break
end
end
if match then return true end
end
return false
end

return {
is_image = is_image,
}
2 changes: 1 addition & 1 deletion lua/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

---@class API
---@field setup fun(options?: Options)
---@field from_file fun(path: string, options?: ImageOptions): Image
---@field from_file fun(path: string, options?: ImageOptions): Image|nil
---@field from_url fun(url: string, options?: ImageOptions, callback: fun(image: Image|nil))
---@field clear fun(id?: string)
---@field get_images fun(opts?: { window?: number, buffer?: number }): Image[]
Expand Down

0 comments on commit 4c1c903

Please sign in to comment.