local player = require'cplayer' local libpng = require'libpng' local glue = require'glue' local ffi = require'ffi' require'unit' --dir local good_files = dir'media/png/good/*.png' local bad_files = dir'media/png/bad/*.png' local source_type = 'path' local files = good_files local bottom_up = false local stride_aligned = false local max_cut_size = 1024 * 6 local cut_size = max_cut_size local pixel_format = 'rgb' local interlaced_filter_values = {'interl', 'normal'} local interlaced_filter = glue.index(interlaced_filter_values) local paletted_filter_values = {'pal', 'bitmap'} local paletted_filter = glue.index(paletted_filter_values) local channels_filter_values = {'rgb', 'rgba', 'g', 'ga'} local channels_filter = glue.index(channels_filter_values) local bpc_filter_values = {'1b', '2b', '4b', '8b', '16b'} local bpc_filter = glue.index(bpc_filter_values) local passes_filter_values = {'single', 'multi'} local passes_filter = glue.index(passes_filter_values) local pass_only = 7 local sparkle = false function player:on_render(cr) self:checkerboard() files = self:mbutton{id = 'files', x = 10, y = 10, w = 180, h = 24, values = {good_files, bad_files}, texts = {[good_files] = 'good files', [bad_files] = 'bad files'}, multiselect = false, selected = files} source_type = self:mbutton{id = 'source_type', x = 200, y = 10, w = 490, h = 24, values = {'path', 'stream', 'cdata', 'string', 'read cdata', 'read string'}, selected = source_type} sparkle = self:togglebutton{id = 'sparkle', x = 700, y = 10, w = 90, h = 24, text = 'sparkle', selected = sparkle} bottom_up = self:togglebutton{id = 'bottom_up', x = 800, y = 10, w = 90, h = 24, text = 'bottom_up', selected = bottom_up} stride_aligned = self:togglebutton{id = 'stride_aligned', x = 900, y = 10, w = 90, h = 24, text = 'stride_aligned', selected = stride_aligned} if source_type ~= 'path' and source_type ~= 'stream' then cut_size = self:slider{id = 'cut_size', x = 1000, y = 10, w = self.w - 1000 - 10, h = 24, i0 = 0, i1 = max_cut_size, step = 1, i = cut_size, text = 'file cut'} end pixel_format = self:mbutton{id = 'pixel', x = 10, y = 40, w = 380, h = 24, values = {'rgb', 'bgr', 'rgba', 'bgra', 'argb', 'abgr', 'g', 'ga', 'ag'}, selected = pixel_format} interlaced_filter = self:mbutton{id = 'interlaced_filter', x = 400, y = 40, w = 90, h = 24, values = interlaced_filter_values, selected = interlaced_filter} paletted_filter = self:mbutton{id = 'paletted_filter', x = 500, y = 40, w = 90, h = 24, values = paletted_filter_values, selected = paletted_filter} channels_filter = self:mbutton{id = 'channels_filter', x = 600, y = 40, w = 190, h = 24, values = channels_filter_values, selected = channels_filter} bpc_filter = self:mbutton{id = 'bpc_filter', x = 800, y = 40, w = 190, h = 24, values = bpc_filter_values, selected = bpc_filter} passes_filter = self:mbutton{id = 'passes_filter', x = 1000, y = 40, w = 90, h = 24, values = passes_filter_values, selected = passes_filter} pass_only = self:slider{id = 'pass_only', x = 1100, y = 40, w = 90, h = 24, i0 = 1, i1 = 7, i = pass_only, text = 'pass'} local function allow_image(image) if not interlaced_filter.interl and image.file.interlaced then return end if not interlaced_filter.normal and not image.file.interlaced then return end if not paletted_filter.pal and image.file.paletted then return end if not paletted_filter.bitmap and not image.file.paletted then return end if not bpc_filter[tostring(image.file.bpc)..'b'] then return end if not channels_filter[image.file.channels] then return end if not passes_filter.single and image.file.passes == 1 then return end if not passes_filter.multi and image.file.passes == 7 then return end return true end local cy = 80 local cx = 10 for i,filename in ipairs(files) do local t = {} if source_type == 'path' then t.path = filename elseif source_type == 'stream' then t.stream = io.open(filename, 'rb') else local s = glue.readfile(filename) s = s:sub(1, cut_size) local cdata = ffi.new('uint8_t[?]', #s+1, s) if source_type == 'cdata' then t.cdata = cdata t.size = #s elseif source_type == 'string' then t.string = s elseif source_type:match'^read' then local function one_shot_reader(buf, sz) local done return function() if done then return end done = true return buf, sz end end if source_type:find'string' then t.read = one_shot_reader(s) else t.read = one_shot_reader(cdata, #s) end end end local w, h = 32, 32 --[[ t.accept = { [pixel_format] = true, bottom_up = bottom_up, stride_aligned = stride_aligned} ]] t.sparkle = sparkle function t.render_scan(image, last_scan, scan_number, err) if scan_number ~= pass_only and not (pass_only > 1 and scan_number == 1 and last_scan) then return end if not image then w = (w + 10) * 8 - 10 end if cx + w + 10 > self.w then cx = 10 cy = cy + h + 10 + 40 end if image then self:image{x = cx, y = cy, image = image} self:textbox(cx, cy - 16, w, h, string.format('%s', image.file.format), 8, 'normal_fg', 'center', 'top') self:textbox(cx, cy + 16, w, h, string.format('%s', image.format), 8, 'normal_fg', 'center', 'bottom') else self:rect(cx, cy, w, h, 'error_bg') self:textbox(cx, cy, w, h, string.format('%s', err:match('^(.-)\n'):match(': ([^:]-)$')), 14, 'normal_fg', 'center', 'center') end cx = cx + w + 10 end local ok, err = xpcall(function() local t0 = glue.merge({ header_only = true, render_scan = false, }, t) local image = libpng.load(t0) if not allow_image(image) then return end libpng.load(t) end, debug.traceback) if not ok then t.render_scan(nil, true, 1, err) end if t.stream then t.stream:close() end end end player:play()