You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

519 lines
16 KiB

  1. --[===================================================================[--
  2. Copyright © 2016, 2018 Pedro Gimeno Fortea. All rights reserved.
  3. Permission is hereby granted to everyone to copy and use this file,
  4. for any purpose, in whole or in part, free of charge, provided this
  5. single condition is met: The above copyright notice, together with
  6. this permission grant and the disclaimer below, should be included
  7. in all copies of this software or of a substantial portion of it.
  8. THIS SOFTWARE COMES WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED.
  9. --]===================================================================]--
  10. -- GIF(sm) image decoder for the love2d framework, using LuaJIT + FFI.
  11. -- Includes LZW decompression.
  12. local ffi = require 'ffi'
  13. local bit = require 'bit'
  14. -- We have a "double buffer" coroutine-based consumer-producer system
  15. -- requiring the consumer to not request large chunks at a time
  16. -- otherwise the buffer would overflow (this is detected but it will
  17. -- cause an assertion error).
  18. local bytearray = ffi.typeof('uint8_t[?]')
  19. local intarray = ffi.typeof('int[?]')
  20. local int32ptr = ffi.typeof('int32_t *')
  21. -- Interlaced mode table. Format:
  22. -- {initial value for pass 1, increment for pass 1,
  23. -- initial value for pass 2, increment for pass 2, ...}
  24. local intertable = {0, 8, 4, 8, 2, 4, 1, 2, false}
  25. -- Utility function for error propagation
  26. local function coresume(co, ...)
  27. local ok, err = coroutine.resume(co, ...)
  28. if not ok then
  29. error(err)
  30. end
  31. end
  32. -- Consumer
  33. local function gifread(self, length)
  34. while self.ptr + length >= self.buflen do
  35. coroutine.yield() -- wait for more input
  36. end
  37. local tmp = self.ptr
  38. self.ptr = self.ptr + length
  39. if tmp >= 24576 then -- this leaves 8192 as max read length (768 would probably suffice)
  40. ffi.copy(self.buffer, self.buffer + tmp, self.buflen - tmp)
  41. self.buflen = self.buflen - tmp
  42. self.ptr = self.ptr - tmp
  43. tmp = 0
  44. end
  45. return tmp, length
  46. end
  47. -- Producer - prepare the data for the consumer
  48. local function gifupdate(self, s)
  49. if #s > 32768 then
  50. -- Creating a Lua string object is an expensive operation.
  51. -- Do it as seldom as possible. We split the input data
  52. -- into 32K chunks.
  53. for i = 1, #s, 32768 do
  54. gifupdate(self, s:sub(i, i + 32767))
  55. end
  56. return
  57. end
  58. if coroutine.status(self.decoder) == "dead" then
  59. -- feeding data after the decoding is finished, ignore
  60. return
  61. end
  62. assert(self.buflen <= 32768, "Buffer overflow")
  63. ffi.copy(self.buffer + self.buflen, s, #s)
  64. self.buflen = self.buflen + #s
  65. coresume(self.decoder)
  66. return self
  67. end
  68. local function gifdone(self)
  69. -- free C memory immediately
  70. self.buffer = false
  71. return self
  72. end
  73. local function giferr(self, msg)
  74. print(msg)
  75. end
  76. -- Gif decoding aux functions
  77. local function gifpalette(palette, source, psize)
  78. -- Read a palette, inserting alpha
  79. for i = 0, psize - 1 do
  80. palette[i*4] = source[i*3]
  81. palette[i*4 + 1] = source[i*3 + 1]
  82. palette[i*4 + 2] = source[i*3 + 2]
  83. palette[i*4 + 3] = 255
  84. end
  85. end
  86. -- Gif decoder proper
  87. local function gifdecoder(self)
  88. -- Read file ID and header
  89. local buffer = self.buffer
  90. gifread(self, 13)
  91. if ffi.string(self.buffer, 6) ~= 'GIF87a'
  92. and ffi.string(self.buffer, 6) ~= 'GIF89a'
  93. then
  94. self:err('Invalid GIF file format')
  95. return
  96. end
  97. self.width = buffer[6] + 256*buffer[7]
  98. self.height = buffer[8] + 256*buffer[9]
  99. local gpalettesize = buffer[10] >= 128 and bit.lshift(1, bit.band(buffer[10], 7) + 1) or 0
  100. local background = buffer[11]
  101. self.aspect = ((buffer[12] == 0 and 49 or 0) + 15) / 64
  102. local gpalette = bytearray(256*4)
  103. local lpalette = bytearray(256*4)
  104. local lpalettesize
  105. -- Read palette and set background
  106. self.background = background -- default value
  107. if gpalettesize > 0 then
  108. gifread(self, gpalettesize * 3)
  109. gifpalette(gpalette, buffer + 13, gpalettesize)
  110. if background < gpalettesize then
  111. self.background = {gpalette[background*4], gpalette[background*4+1], gpalette[background*4+2]}
  112. end
  113. end
  114. local p
  115. local GCE_trans = false
  116. local GCE_dispose = 0
  117. local GCE_delay = 0
  118. -- Allocate the buffers in advance, to reuse them for every frame
  119. local dict = bytearray(4096)
  120. local dictptrs = intarray(4096)
  121. local reversebuf = bytearray(4096)
  122. repeat
  123. -- Get block type
  124. p = gifread(self, 1)
  125. local blocktype = 0x3B
  126. local blocklen
  127. -- for simplicity (?), we fuse the block type and the extension type into
  128. -- 'blocktype'
  129. if buffer[p] == 0x2C then
  130. -- Image block
  131. blocktype = 0x2C
  132. elseif buffer[p] == 0x21 then
  133. -- Extension block
  134. p = gifread(self, 1)
  135. blocktype = buffer[p]
  136. if blocktype == 0x2C then
  137. -- there's no extension 2C - terminate
  138. -- (avoids ambiguity with block type 2C)
  139. blocktype = 0x3B
  140. end
  141. elseif buffer[p] ~= 0x3B then
  142. self:err(string.format("Unknown block type: 0x%02X", buffer[p]))
  143. break
  144. end
  145. if blocktype == 0x3B then
  146. -- Trailer block or invalid block - terminate
  147. break
  148. elseif blocktype == 0xFF then
  149. -- Application extension - may be loop, otherwise skip
  150. p = gifread(self, 1)
  151. blocklen = buffer[p]
  152. p = gifread(self, blocklen + 1)
  153. if blocklen >= 11 and ffi.string(buffer + p, 11) == 'NETSCAPE2.0' then
  154. -- these *are* the androids we're looking for
  155. p = p + blocklen
  156. while buffer[p] ~= 0 do
  157. local sblen = buffer[p]
  158. p = gifread(self, sblen + 1) -- read also the next block length
  159. if buffer[p] == 1 and sblen >= 3 then
  160. -- looping subblock - that's for us
  161. self.loop = buffer[p + 1] + 256 * buffer[p + 2]
  162. end
  163. p = p + sblen -- advance to next block
  164. end
  165. else
  166. -- skip entire block
  167. p = p + blocklen
  168. while buffer[p] ~= 0 do
  169. gifread(self, buffer[p])
  170. p = gifread(self, 1)
  171. end
  172. end
  173. elseif blocktype == 0x01 or blocktype == 0xFE then
  174. -- Text or Comment Extension - not processed by us, skip
  175. p = gifread(self, 1) -- read length
  176. if blocktype < 0x01 then
  177. -- skip the block header (contains a length field)
  178. p = gifread(self, buffer[p] + 1) + buffer[p]
  179. -- the text extension "consumes" the GCE, so we clear it
  180. GCE_trans = false
  181. GCE_dispose = 0
  182. GCE_delay = 0
  183. end
  184. while buffer[p] ~= 0 do
  185. p = gifread(self, buffer[p] + 1) + buffer[p]
  186. end
  187. elseif blocktype == 0xF9 then
  188. -- Graphic Control Extension
  189. p = gifread(self, 1)
  190. blocklen = buffer[p]
  191. p = gifread(self, blocklen + 1)
  192. if blocklen >= 4 then
  193. GCE_delay = (buffer[p+1] + 256 * buffer[p+2]) / 100
  194. GCE_trans = bit.band(buffer[p], 1) ~= 0 and buffer[p + 3]
  195. GCE_dispose = bit.rshift(bit.band(buffer[p], 0x1C), 2)
  196. end
  197. p = p + blocklen
  198. while buffer[p] ~= 0 do
  199. p = gifread(self, buffer[p] + 1) + buffer[p]
  200. end
  201. elseif blocktype == 0x2C then
  202. -- Here be dragons
  203. p = gifread(self, 9)
  204. local x, y = buffer[p] + 256*buffer[p+1], buffer[p+2] + 256*buffer[p+3]
  205. local w, h = buffer[p+4] + 256*buffer[p+5], buffer[p+6] + 256*buffer[p+7]
  206. if w == 0 or h == 0 then
  207. self:err('Zero size image')
  208. break
  209. end
  210. local img = love.image.newImageData(w, h)
  211. local dataptr = ffi.cast(int32ptr, img:getPointer())
  212. self.imgs[#self.imgs + 1] = GCE_dispose
  213. self.imgs[#self.imgs + 1] = GCE_delay
  214. self.imgs[#self.imgs + 1] = img
  215. self.imgs[#self.imgs + 1] = x
  216. self.imgs[#self.imgs + 1] = y
  217. self.nimages = self.nimages + 1
  218. local flags = buffer[p+8]
  219. if flags >= 128 then
  220. -- Has local palette
  221. lpalettesize = bit.lshift(1, bit.band(flags, 7) + 1)
  222. p = gifread(self, lpalettesize*3)
  223. gifpalette(lpalette, buffer + p, lpalettesize)
  224. else
  225. -- No local palette - copy the global palette to the local one
  226. ffi.copy(lpalette, gpalette, gpalettesize*4)
  227. lpalettesize = gpalettesize
  228. end
  229. if GCE_trans and GCE_trans < lpalettesize then
  230. -- Clear alpha
  231. lpalette[GCE_trans*4 + 3] = 0
  232. end
  233. local interlace = bit.band(flags, 64) ~= 0 and 1
  234. -- LZW decoder.
  235. -- This could really use another coroutine for
  236. -- simplicity, as there's another producer/consumer,
  237. -- but we won't go there.
  238. p = gifread(self, 2)
  239. local LZWsize = buffer[p]
  240. p = p + 1
  241. if LZWsize == 0 or LZWsize > 11 then
  242. self:err("Invalid code size")
  243. break
  244. end
  245. local codebits = LZWsize + 1
  246. local clearcode = bit.lshift(1, LZWsize) -- End-of-stream is always clearcode+1
  247. local dictlen = clearcode + 2
  248. local bitstream, bitlen = 0, 0
  249. x, y = 0, 0
  250. local nextlenptr = p
  251. local oldcode
  252. local walkcode
  253. local nrows = 0 -- counts vertical rows, used because interlacing makes the last y invalid
  254. local row = 0
  255. repeat
  256. -- Are there enough bits in curcode? Do we need to read more data?
  257. if bitlen >= codebits and y then
  258. -- Extract next code
  259. local code = bit.band(bitstream, bit.lshift(1, codebits) - 1)
  260. bitstream = bit.rshift(bitstream, codebits)
  261. bitlen = bitlen - codebits
  262. if code == clearcode then
  263. codebits = LZWsize + 1
  264. dictlen = clearcode + 2
  265. oldcode = false
  266. elseif code == clearcode + 1 then
  267. if x ~= 0 or nrows ~= h then
  268. self:err("Soft EOD before all rows were output")
  269. end
  270. -- signal end of processing
  271. -- (further data won't be read, but we need to follow the blocks)
  272. y = false
  273. else
  274. -- The dictionary is stored as a list of back pointers.
  275. -- We need to reverse the order to output the entries.
  276. -- We use a reverse buffer for that.
  277. local reverseptr = 4095
  278. -- Is this code already in the table?
  279. if code < dictlen then
  280. -- Already in the table - get the string from the table
  281. walkcode = code
  282. while walkcode >= clearcode do
  283. reversebuf[reverseptr] = dict[walkcode]
  284. reverseptr = reverseptr - 1
  285. walkcode = dictptrs[walkcode]
  286. end
  287. reversebuf[reverseptr] = walkcode
  288. -- Add to the table
  289. if oldcode then
  290. if dictlen < 4096 then
  291. dictptrs[dictlen] = oldcode
  292. dict[dictlen] = walkcode
  293. dictlen = dictlen + 1
  294. if dictlen ~= 4096 and bit.band(dictlen, dictlen - 1) == 0 then
  295. -- perfect power of two - increase code size
  296. codebits = codebits + 1
  297. end
  298. end
  299. end
  300. oldcode = code
  301. else
  302. -- Not in the table - deal with the special case
  303. -- The compressor has created a new code, which must be the next
  304. -- in sequence. We know what it must contain.
  305. -- It must contain oldcode + first character of oldcode.
  306. if code > dictlen or not oldcode or not walkcode then
  307. self:err("Broken LZW")
  308. break
  309. end
  310. -- Add to the table
  311. if oldcode then
  312. if dictlen < 4096 then
  313. dictptrs[dictlen] = oldcode
  314. dict[dictlen] = walkcode
  315. dictlen = dictlen + 1
  316. if dictlen ~= 4096 and bit.band(dictlen, dictlen - 1) == 0 then
  317. -- perfect power of two - increase code size
  318. codebits = codebits + 1
  319. end
  320. end
  321. end
  322. oldcode = code
  323. walkcode = oldcode
  324. while walkcode >= clearcode do
  325. reversebuf[reverseptr] = dict[walkcode]
  326. reverseptr = reverseptr - 1
  327. walkcode = dictptrs[walkcode]
  328. end
  329. reversebuf[reverseptr] = walkcode
  330. end
  331. if y then
  332. for i = reverseptr, 4095 do
  333. local c = reversebuf[i]
  334. if c >= lpalettesize then c = 0 end
  335. c = ffi.cast(int32ptr, lpalette)[c]
  336. dataptr[x + row] = c
  337. if interlace then
  338. -- The passes 1, 2, 3, 4 correspond to the
  339. -- values 1, 3, 5, 7 of 'interlace'.
  340. if self.progressive and interlace < 7 and y + 1 < h then
  341. -- In any pass but the last, there are at least 2 lines.
  342. dataptr[x + row + w] = c
  343. if interlace < 5 and y + 2 < h then
  344. -- In the first two passes, there are at least 4 lines.
  345. dataptr[x + row + w*2] = c
  346. if y + 3 < h then
  347. dataptr[x + row + w*3] = c
  348. if interlace < 3 and y + 4 < h then
  349. -- In the first pass there are 8 lines.
  350. dataptr[x + row + w*4] = c
  351. if y + 5 < h then
  352. dataptr[x + row + w*5] = c
  353. if y + 6 < h then
  354. dataptr[x + row + w*6] = c
  355. if y + 7 < h then
  356. dataptr[x + row + w*7] = c
  357. end
  358. end
  359. end
  360. end
  361. end
  362. end
  363. end
  364. -- Advance pixel
  365. x = x + 1
  366. if x >= w then
  367. -- Skip to next interlaced row
  368. x = 0
  369. nrows = nrows + 1
  370. y = y + intertable[interlace + 1]
  371. if y >= h then
  372. interlace = interlace + 2
  373. if interlace > 7 then
  374. y = false
  375. else
  376. y = intertable[interlace]
  377. end
  378. end
  379. if y then
  380. row = y * w
  381. end
  382. end
  383. else
  384. -- No interlace, just increment y
  385. x = x + 1
  386. if x >= w then
  387. x = 0
  388. y = y + 1
  389. nrows = y
  390. if y >= h then
  391. y = false
  392. else
  393. row = y * w
  394. end
  395. end
  396. end
  397. end
  398. else
  399. -- This should not happen.
  400. self:err('Data past the end of the image')
  401. end
  402. end
  403. else
  404. -- Not enough bits, grab 8 more
  405. if p >= nextlenptr then
  406. -- End of this subblock - read next subblock
  407. assert(p == nextlenptr)
  408. local sblen = buffer[nextlenptr]
  409. if sblen == 0 then
  410. -- no more data
  411. if y then
  412. self:err("Hard EOD before the end of the image")
  413. end
  414. break
  415. end
  416. p = gifread(self, sblen + 1)
  417. nextlenptr = p + sblen
  418. end
  419. if y then
  420. bitstream = bitstream + bit.lshift(buffer[p], bitlen)
  421. bitlen = bitlen + 8
  422. p = p + 1
  423. else
  424. -- end of data - fast forward to end of block
  425. p = nextlenptr
  426. end
  427. end
  428. until false
  429. GCE_trans = false
  430. GCE_dispose = 0
  431. GCE_delay = 0
  432. self.ncomplete = self.nimages
  433. else
  434. break
  435. end
  436. until false
  437. end
  438. local function gifframe(self, n)
  439. n = (n-1) % self.nimages + 1
  440. return self.imgs[n*5-2], self.imgs[n*5-1], self.imgs[n*5], self.imgs[n*5-3], self.imgs[n*5-4]
  441. end
  442. local function gifnew(retver)
  443. if retver == "version" then
  444. return 0x010002
  445. -- else just ignore it and create the object
  446. end
  447. local self = {
  448. update = gifupdate;
  449. done = gifdone;
  450. frame = gifframe;
  451. err = giferr;
  452. background = false;
  453. width = false;
  454. height = false;
  455. imgs = {};
  456. nimages = 0;
  457. ncomplete = 0;
  458. buffer = bytearray(65536);
  459. buflen = 0;
  460. ptr = 0;
  461. progressive = false;
  462. loop = false;
  463. aspect = false;
  464. decoder = coroutine.create(gifdecoder);
  465. }
  466. -- pass self to the coroutine (will return immediately for lack of data)
  467. coresume(self.decoder, self)
  468. return self
  469. end
  470. return gifnew