Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local tags = {"&f", "&6", "&f", "&b", "&e", "&a", "&d", "&8", "&7", "&3", "&5", "&1", "&f", "&2", "&c", "&0"}
- local reverseTags = {}
- for k,v in pairs(tags) do
- reverseTags[v] = k-1
- end
- function loadCBM(sFile, useTags, noAnimation)
- if (not fs.exists(sFile)) or fs.isDir(sFile)
- then return nil, "Invalid file or directory"
- else
- local file = fs.open(sFile, "rb")
- if not file then return nil, "Invalid file or directory 2" end
- --[[local]] bytes = {}
- byteCopy = {}
- while true do
- local byte = file.read()
- if not byte then break end
- table.insert(bytes, byte)
- table.insert(byteCopy, byte)
- end
- file.close()
- --[[local]] width, height = 0, 0
- if #bytes < 12 then return nil, "Invalid image" end
- for i=1,3 do
- if table.remove(bytes,1) ~= string.byte("CBM", i) then return nil, "Not a CBM file" end
- end
- for byteNum=3,0,-1 do
- height = height + (2^byteNum)*table.remove(bytes,1)
- end
- for byteNum=3,0,-1 do
- width = width + (2^byteNum)*table.remove(bytes,1)
- end
- --[[local]] flags = table.remove(bytes, 1)
- --[[local]] trans = bit.band(flags, 1) ~= 0; flags = bit.brshift(flags, 1)
- --[[local]] animated = bit.band(flags, 1) ~= 0; flags = bit.brshift(flags, 1)
- --[[local]] reps = table.remove(bytes, 1)
- --[[local]] interval = table.remove(bytes, 1) + 1
- --[[local]] imgBytes = math.ceil(width*height/2)
- --[[local]] alphaBytes = trans and math.ceil(width*height/8) or 0
- if #bytes%(imgBytes+alphaBytes)~=0 then return nil, "Invalid image 2" end
- local frameNum = animated and #bytes/(imgBytes+alphaBytes) or 1
- local frames = {}
- for _=1,noAnimation and 1 or frameNum do
- local pixels = {}
- local pixelList = {}
- local bitMask = {}
- for i=1,imgBytes do
- local byte = table.remove(bytes, 1)
- table.insert(pixelList, 1, math.floor(byte/16))
- table.insert(pixelList, 1, byte%16)
- if useTags then
- for i=1,2 do
- pixelList[i] = tags[pixelList[i]+1]
- end
- end
- end
- if trans then
- for i=1,alphaBytes do
- local insertPoint = #bitMask + 1
- local byte = table.remove(bytes, 1)
- for j=1,8 do
- --[[if ((i-1)*8)+j<=width*height then]] table.insert(bitMask, insertPoint, bit.band(byte, 1)) --end
- bit.brshift(byte, 1)
- end
- end
- end
- if (width*height)%2 == 1 then pixelList[#pixelList] = nil end
- for row=1,height do
- pixels[row] = {}
- for column=1,width do
- pixels[row][column] = table.remove(pixelList)
- if trans then
- if table.remove(bitMask, 1) == 1 then
- pixels[row][column] = -1
- end
- end
- end
- end
- table.insert(frames, pixels)
- end
- if not noAnimation then frames.interval = interval end
- if not noAnimation then frames.repetitions = (reps == 0) and math.huge or reps end
- return noAnimation and frames[1] or frames
- end
- end
- function saveCBM( sFile, frames, trans)
- t = trans
- function toBytes(number, byteCount)
- local byteCount = byteCount or 4
- local byteTable = {}
- for _=1,byteCount do
- table.insert(byteTable, 1, number%256)
- number=(number-byteTable[1])/256
- end
- return byteTable
- end
- if not (frames and sFile) then return nil, "Invalid argument" end
- local reps = frames.repetitions or 0
- if reps == math.huge then reps = 0 end
- if reps > 255 then reps = 255 end
- local interval = frames.interval or 10
- if interval > 255 then interval = 255 end
- --[[local]] animated = type(frames[1][1]) == "table"
- local bytes = {string.byte("CBM", 1, 3)}
- local pixels = animated and frames[1] or frames
- frames = animated and frames or {frames}
- local height = #pixels
- if height == 0 then return nil, "Empty image" end
- local width = #pixels[1]
- for i=2,height do
- if #pixels[i] ~= width then return nil, "Invalid image" end
- end
- local widthBytes = toBytes(width)
- local heightBytes = toBytes(height)
- for i=1,4 do
- table.insert(bytes, heightBytes[i])
- end
- for i=1,4 do
- table.insert(bytes, widthBytes[i])
- end
- --[[local]] flags = 0
- flags = flags + (animated and 1 or 0)
- flags = bit.blshift(flags, 1); flags = flags + (trans and 1 or 0)
- table.insert(bytes, flags)
- table.insert(bytes, reps)
- table.insert(bytes, interval)
- for _,pixels in ipairs(frames) do
- local bitMask = {}
- for row = 1,height do
- for column = 1,width,2 do
- pixels[row][2] = pixels[row][2] or 0
- for i=1,2 do
- if type(pixels[row][i]) ~= "number" then
- if string.sub(pixels[row][i],1,1) == "&" then
- pixels[row][i] = reverseTags[pixels[row][i]]
- else return nil, "Invalid pixel: "..row..", "..column+i-1
- end
- end
- end
- if pixels[row][1] > 15 or pixels[row][2] > 15 or pixels[row][1] < -1 or pixels[row][2] < -1 then return nil, "Invalid pixel 2: "..row..", "..column end
- if pixels[row][1] == -1 then pixels[row][1] = 0 table.insert(bitMask, 1) else table.insert(bitMask, 0) end
- if pixels[row][2] == -1 then pixels[row][2] = 0 table.insert(bitMask, 1) else table.insert(bitMask, 0) end
- table.insert(bytes, table.remove(pixels[row],1)*16 + table.remove(pixels[row],1))
- end
- end
- while #bitMask%8~=0 do table.insert(bitMask, 0) end
- if trans then
- for i=1,#bitMask,8 do
- local byte = 0
- for j=0,7 do
- byte = byte + 2^(7-j) * bitMask[i+j]
- end
- table.insert(bytes, byte)
- end
- end
- end
- local yieldcount = 0
- local file = fs.open(sFile, "wb")
- for _,byte in ipairs(bytes) do
- yieldcount = yieldcount + 1
- if yieldcount >= 64 then os.queueEvent(".") os.pullEvent(".") yieldcount = 0 end
- file.write(byte)
- end
- file.close()
- return true
- end
Advertisement
Add Comment
Please, Sign In to add comment