BinUtils.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. --Binary Utilities.
  2. --Variabes.
  3. local sw,sh = screenSize()
  4. --Localized Lua Library
  5. local unpack = unpack
  6. local floor, ceil, min = math.floor, math.ceil, math.min
  7. local strChar, strByte = string.char, string.byte
  8. local lshift, rshift, bor, band, bxor = bit.lshift, bit.rshift, bit.bor, bit.band, bit.bxor
  9. --The API
  10. local BinUtils = {}
  11. BinUtils.Null = strChar(0) --The null character
  12. --==Images==--
  13. --Encode an image into binary.
  14. function BinUtils.imgToBin(img,getTable)
  15. if img:typeOf("GPU.image") then img = img:data() end --Convert the image to imagedata.
  16. local bin = {}
  17. local imgW, imgH = img:size()
  18. local flag = true
  19. img:map(function(x,y,c)
  20. x = x + y*imgW + 1
  21. local byte = bin[ceil(x/2)] or 0
  22. if flag then
  23. byte = bor(byte,lshift(c,4))
  24. else
  25. byte = bor(byte,c)
  26. end
  27. bin[ceil(x/2)] = byte
  28. flag = not flag
  29. end)
  30. if getTable then return bin end
  31. for k,v in pairs(bin) do
  32. bin[k] = strChar(v)
  33. end
  34. return table.concat(bin)
  35. end
  36. --Load an image from binary.
  37. function BinUtils.binToImg(img,bin)
  38. local colors, cid = {}, 1
  39. for i=1,bin:len() do
  40. local byte = strByte(bin,i)
  41. local left = band(byte,0xF0)
  42. colors[cid] = rshift(left,4)
  43. colors[cid+1] = band(byte,0x0F)
  44. cid = cid + 2
  45. end
  46. cid = 1
  47. img:map(function(x,y,old)
  48. local c = colors[cid] or 0
  49. cid = cid + 1
  50. return c
  51. end)
  52. end
  53. --==Maps==--
  54. --Encode a map into binary.
  55. function BinUtils.mapToBin(map,getTable)
  56. local bin = {}
  57. local tid = 1
  58. map:map(function(x,y,tile)
  59. bin[tid] = min(tile,255)
  60. tid = tid + 1
  61. end)
  62. if getTable then return bin end
  63. for k,v in pairs(bin) do
  64. bin[k] = strChar(v)
  65. end
  66. return table.concat(bin)
  67. end
  68. --Load a map from binary.
  69. function BinUtils.binToMap(map,bin)
  70. local len, id = bin:len(), 0
  71. map:map(function(x,y,tile)
  72. id = id + 1
  73. return (id <= len and strByte(bin,id) or 0)
  74. end)
  75. end
  76. --==Code==--
  77. --Encode code into binary.
  78. function BinUtils.codeToBin(code)
  79. return math.compress(code,"gzip",9)
  80. end
  81. --Load code from binary.
  82. function BinUtils.binToCode(bin)
  83. return math.decompress(bin,"gzip",9)
  84. end
  85. --==Extra==--
  86. --Encode a number into binary
  87. function BinUtils.numToBin(num,length,getTable)
  88. local bytes = {}
  89. for bnum=1,length do
  90. bytes[bnum] = band(num,255)
  91. num = rshift(num,8)
  92. end
  93. if getTable then return bytes end
  94. return strChar(unpack(bytes))
  95. end
  96. --Load a number from binary
  97. function BinUtils.binToNum(bin)
  98. local number = 0
  99. for i=1,bin:len() do
  100. local byte = strByte(bin,i)
  101. byte = lshift(byte,(i-1)*8)
  102. number = bor(number,byte)
  103. end
  104. return number
  105. end
  106. --Calculate the length of the number in bytes
  107. function BinUtils.numLength(num)
  108. local length = 0
  109. while num > 0 do
  110. num = rshift(num,8)
  111. length = length + 1
  112. end
  113. return length
  114. end
  115. --Create a binary iterator for a string
  116. function BinUtils.binIter(bin)
  117. local counter = 0
  118. return function()
  119. counter = counter + 1
  120. return strByte(bin,counter)
  121. end, function()
  122. return counter
  123. end
  124. end
  125. --Create a binary writer
  126. function BinUtils.binWriter()
  127. local bytes, bid, byte, bpos = {}, 1, 0, 0
  128. return function(bits,count)
  129. if bits then
  130. byte = lshift(byte,count)
  131. byte = bor(byte,bits)
  132. bpos = bpos + count
  133. if bpos >= 8 then
  134. local cbyte = rshift(byte,bpos-8)
  135. byte = bxor(byte,lshift(cbyte,bpos-8))
  136. bpos = bpos - 8
  137. bytes[bid] = strChar(cbyte)
  138. bid = bid + 1
  139. end
  140. else --Generate the string
  141. if bpos > 0 then
  142. bytes[bid] = strChar(byte)
  143. end
  144. return table.concat(bytes)
  145. end
  146. end
  147. end
  148. --Create a bin reader
  149. function BinUtils.binReader(data)
  150. local bid, byte, bc = 1, 0, 0
  151. return function(c)
  152. if c > bc then
  153. byte = lshift(byte,8)
  154. byte = bxor(byte,strByte(data,bid))
  155. bc = bc + 8
  156. bid = bid + 1
  157. end
  158. local bits = rshift(byte,bc-c)
  159. byte = bxor(byte,lshift(bits,bc-c))
  160. bc = bc - c
  161. return bits
  162. end
  163. end
  164. --Make the ramutils a global
  165. _G["BinUtils"] = BinUtils