PageRenderTime 63ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/Library/BdsDxe/Graphics/picopng.c

https://github.com/SunnyKi/bareBoot
C | 1507 lines | 1331 code | 128 blank | 48 comment | 377 complexity | 3ab1f0a44005824c464c58491f7ee61b MD5 | raw file
  1. // picoPNG version 20080503 (cleaned up and ported to c by kaitek)
  2. // Copyright (c) 2005-2008 Lode Vandevenne
  3. //
  4. // This software is provided 'as-is', without any express or implied
  5. // warranty. In no event will the authors be held liable for any damages
  6. // arising from the use of this software.
  7. //
  8. // Permission is granted to anyone to use this software for any purpose,
  9. // including commercial applications, and to alter it and redistribute it
  10. // freely, subject to the following restrictions:
  11. //
  12. // 1. The origin of this software must not be misrepresented; you must not
  13. // claim that you wrote the original software. If you use this software
  14. // in a product, an acknowledgment in the product documentation would be
  15. // appreciated but is not required.
  16. // 2. Altered source versions must be plainly marked as such, and must not be
  17. // misrepresented as being the original software.
  18. // 3. This notice may not be removed or altered from any source distribution.
  19. #include <Library/MemoryAllocationLib.h>
  20. #include "picopng.h"
  21. /*************************************************************************************************/
  22. typedef struct png_alloc_node {
  23. struct png_alloc_node *prev, *next;
  24. VOID *addr;
  25. UINT32 size;
  26. } png_alloc_node_t;
  27. png_alloc_node_t *png_alloc_head = NULL;
  28. png_alloc_node_t *png_alloc_tail = NULL;
  29. png_alloc_node_t *
  30. png_alloc_find_node (
  31. VOID *addr
  32. )
  33. {
  34. png_alloc_node_t *node;
  35. for (node = png_alloc_head; node; node = node->next)
  36. if (node->addr == addr)
  37. break;
  38. return node;
  39. }
  40. VOID
  41. png_alloc_add_node (
  42. VOID *addr,
  43. UINT32 size
  44. )
  45. {
  46. png_alloc_node_t *node;
  47. if (png_alloc_find_node (addr))
  48. return;
  49. node = AllocateZeroPool (sizeof (png_alloc_node_t));
  50. node->addr = addr;
  51. node->size = size;
  52. node->prev = png_alloc_tail;
  53. node->next = NULL;
  54. png_alloc_tail = node;
  55. if (node->prev)
  56. node->prev->next = node;
  57. if (!png_alloc_head)
  58. png_alloc_head = node;
  59. }
  60. VOID
  61. png_alloc_remove_node (
  62. png_alloc_node_t * node
  63. )
  64. {
  65. if (node->prev)
  66. node->prev->next = node->next;
  67. if (node->next)
  68. node->next->prev = node->prev;
  69. if (node == png_alloc_head)
  70. png_alloc_head = node->next;
  71. if (node == png_alloc_tail)
  72. png_alloc_tail = node->prev;
  73. node->prev = node->next = node->addr = NULL;
  74. FreePool (node);
  75. }
  76. VOID *
  77. png_alloc_malloc (
  78. UINT32 size
  79. )
  80. {
  81. VOID *addr = AllocateZeroPool (size);
  82. png_alloc_add_node (addr, size);
  83. return addr;
  84. }
  85. VOID *
  86. png_alloc_realloc (
  87. VOID *addr,
  88. UINT32 size
  89. )
  90. {
  91. VOID *new_addr;
  92. if (!addr)
  93. return png_alloc_malloc (size);
  94. new_addr = AllocateZeroPool (size);
  95. if (new_addr != addr) {
  96. png_alloc_node_t *old_node;
  97. old_node = png_alloc_find_node (addr);
  98. png_alloc_remove_node (old_node);
  99. png_alloc_add_node (new_addr, size);
  100. }
  101. return new_addr;
  102. }
  103. VOID
  104. png_alloc_free (
  105. VOID *addr
  106. )
  107. {
  108. png_alloc_node_t *node = png_alloc_find_node (addr);
  109. if (!node)
  110. return;
  111. png_alloc_remove_node (node);
  112. FreePool (addr);
  113. }
  114. VOID
  115. png_alloc_free_all (
  116. )
  117. {
  118. while (png_alloc_tail) {
  119. VOID *addr = png_alloc_tail->addr;
  120. png_alloc_remove_node (png_alloc_tail);
  121. FreePool (addr);
  122. }
  123. }
  124. /*************************************************************************************************/
  125. VOID
  126. vector32_cleanup (
  127. vector32_t * p
  128. )
  129. {
  130. p->size = p->allocsize = 0;
  131. if (p->data)
  132. png_alloc_free (p->data);
  133. p->data = NULL;
  134. }
  135. UINT32
  136. vector32_resize (
  137. vector32_t * p,
  138. UINT32 size
  139. )
  140. { // returns 1 if success, 0 if failure ==> nothing done
  141. if (size * sizeof (UINT32) > p->allocsize) {
  142. UINT32 newsize = size * sizeof (UINT32) * 2;
  143. VOID *data = png_alloc_realloc (p->data, newsize);
  144. if (data) {
  145. p->allocsize = newsize;
  146. p->data = (UINT32 *) data;
  147. p->size = size;
  148. }
  149. else
  150. return 0;
  151. }
  152. else
  153. p->size = size;
  154. return 1;
  155. }
  156. UINT32
  157. vector32_resizev (
  158. vector32_t * p,
  159. UINT32 size,
  160. UINT32 value
  161. )
  162. { // resize and give all new elements the value
  163. UINT32 oldsize = p->size, i;
  164. if (!vector32_resize (p, size))
  165. return 0;
  166. for (i = oldsize; i < size; i++)
  167. p->data[i] = value;
  168. return 1;
  169. }
  170. VOID
  171. vector32_init (
  172. vector32_t * p
  173. )
  174. {
  175. p->data = NULL;
  176. p->size = p->allocsize = 0;
  177. }
  178. vector32_t *
  179. vector32_new (
  180. UINT32 size,
  181. UINT32 value
  182. )
  183. {
  184. vector32_t *p = png_alloc_malloc (sizeof (vector32_t));
  185. vector32_init (p);
  186. if (size && !vector32_resizev (p, size, value))
  187. return NULL;
  188. return p;
  189. }
  190. /*************************************************************************************************/
  191. VOID
  192. vector8_cleanup (
  193. vector8_t * p
  194. )
  195. {
  196. p->size = p->allocsize = 0;
  197. if (p->data)
  198. png_alloc_free (p->data);
  199. p->data = NULL;
  200. }
  201. UINT32
  202. vector8_resize (
  203. vector8_t * p,
  204. UINT32 size
  205. )
  206. { // returns 1 if success, 0 if failure ==> nothing done
  207. // xxx: the use of sizeof UINT32 here seems like a bug (this descends from the lodepng vector
  208. // compatibility functions which do the same). without this there is corruption in certain cases,
  209. // so this was probably done to cover up allocation bug(s) in the original picopng code!
  210. if (size * sizeof (UINT32) > p->allocsize) {
  211. UINT32 newsize = size * sizeof (UINT32) * 2;
  212. VOID *data = png_alloc_realloc (p->data, newsize);
  213. if (data) {
  214. p->allocsize = newsize;
  215. p->data = (UINT8 *) data;
  216. p->size = size;
  217. }
  218. else
  219. return 0; // error: not enough memory
  220. }
  221. else
  222. p->size = size;
  223. return 1;
  224. }
  225. UINT32
  226. vector8_resizev (
  227. vector8_t * p,
  228. UINT32 size,
  229. UINT8 value
  230. )
  231. { // resize and give all new elements the value
  232. UINT32 oldsize = p->size, i;
  233. if (!vector8_resize (p, size))
  234. return 0;
  235. for (i = oldsize; i < size; i++)
  236. p->data[i] = value;
  237. return 1;
  238. }
  239. VOID
  240. vector8_init (
  241. vector8_t * p
  242. )
  243. {
  244. p->data = NULL;
  245. p->size = p->allocsize = 0;
  246. }
  247. vector8_t *
  248. vector8_new (
  249. UINT32 size,
  250. UINT8 value
  251. )
  252. {
  253. vector8_t *p = png_alloc_malloc (sizeof (vector8_t));
  254. vector8_init (p);
  255. if (size && !vector8_resizev (p, size, value))
  256. return NULL;
  257. return p;
  258. }
  259. vector8_t *
  260. vector8_copy (
  261. vector8_t * p
  262. )
  263. {
  264. vector8_t *q = vector8_new (p->size, 0);
  265. UINT32 n;
  266. for (n = 0; n < q->size; n++)
  267. q->data[n] = p->data[n];
  268. return q;
  269. }
  270. /*************************************************************************************************/
  271. const UINT32 LENBASE[29] =
  272. { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
  273. 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
  274. };
  275. const UINT32 LENEXTRA[29] =
  276. { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
  277. 4, 5, 5, 5, 5, 0
  278. };
  279. const UINT32 DISTBASE[30] =
  280. { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
  281. 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
  282. };
  283. const UINT32 DISTEXTRA[30] =
  284. { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
  285. 10, 10, 11, 11, 12, 12, 13, 13
  286. };
  287. // code length code lengths
  288. const UINT32 CLCL[19] =
  289. { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
  290. /*************************************************************************************************/
  291. typedef struct {
  292. // 2D representation of a huffman tree: The one dimension is "0" or "1", the other contains all
  293. // nodes and leaves of the tree.
  294. vector32_t *tree2d;
  295. } HuffmanTree;
  296. HuffmanTree *
  297. HuffmanTree_new (
  298. )
  299. {
  300. HuffmanTree *tree = png_alloc_malloc (sizeof (HuffmanTree));
  301. tree->tree2d = NULL;
  302. return tree;
  303. }
  304. int
  305. HuffmanTree_makeFromLengths (
  306. HuffmanTree * tree,
  307. const vector32_t * bitlen,
  308. UINT32 maxbitlen
  309. )
  310. { // make tree given the lengths
  311. UINT32 bits, n, i;
  312. vector32_t *tree2d;
  313. vector32_t *tree1d, *blcount, *nextcode;
  314. UINT32 numcodes = (UINT32) bitlen->size, treepos = 0, nodefilled = 0;
  315. tree1d = vector32_new (numcodes, 0);
  316. blcount = vector32_new (maxbitlen + 1, 0);
  317. nextcode = vector32_new (maxbitlen + 1, 0);
  318. for (bits = 0; bits < numcodes; bits++)
  319. blcount->data[bitlen->data[bits]]++; // count number of instances of each code length
  320. for (bits = 1; bits <= maxbitlen; bits++)
  321. nextcode->data[bits] =
  322. (nextcode->data[bits - 1] + blcount->data[bits - 1]) << 1;
  323. for (n = 0; n < numcodes; n++)
  324. if (bitlen->data[n] != 0)
  325. tree1d->data[n] = nextcode->data[bitlen->data[n]]++; // generate all the codes
  326. // 0x7fff here means the tree2d isn't filled there yet
  327. tree2d = vector32_new (numcodes * 2, 0x7fff);
  328. tree->tree2d = tree2d;
  329. for (n = 0; n < numcodes; n++) // the codes
  330. for (i = 0; i < bitlen->data[n]; i++) { // the bits for this code
  331. UINT32 bit = (tree1d->data[n] >> (bitlen->data[n] - i - 1)) & 1;
  332. if (treepos > numcodes - 2)
  333. return 55;
  334. if (tree2d->data[2 * treepos + bit] == 0x7fff) { // not yet filled in
  335. if (i + 1 == bitlen->data[n]) { // last bit
  336. tree2d->data[2 * treepos + bit] = n;
  337. treepos = 0;
  338. }
  339. else { // addresses are encoded as values > numcodes
  340. tree2d->data[2 * treepos + bit] = ++nodefilled + numcodes;
  341. treepos = nodefilled;
  342. }
  343. }
  344. else // subtract numcodes from address to get address value
  345. treepos = tree2d->data[2 * treepos + bit] - numcodes;
  346. }
  347. return 0;
  348. }
  349. int
  350. HuffmanTree_decode (
  351. const HuffmanTree * tree,
  352. BOOLEAN *decoded,
  353. UINT32 *result,
  354. UINT32 *treepos,
  355. UINT32 bit
  356. )
  357. { // Decodes a symbol from the tree
  358. const vector32_t *tree2d = tree->tree2d;
  359. UINT32 numcodes = (UINT32) tree2d->size / 2;
  360. if (*treepos >= numcodes)
  361. return 11; // error: you appeared outside the codetree
  362. *result = tree2d->data[2 * (*treepos) + bit];
  363. *decoded = (*result < numcodes);
  364. *treepos = *decoded ? 0 : *result - numcodes;
  365. return 0;
  366. }
  367. /*************************************************************************************************/
  368. int Inflator_error;
  369. UINT32
  370. Zlib_readBitFromStream (
  371. UINT32 *bitp,
  372. const UINT8 *bits
  373. )
  374. {
  375. UINT32 result = (bits[*bitp >> 3] >> (*bitp & 0x7)) & 1;
  376. (*bitp)++;
  377. return result;
  378. }
  379. UINT32
  380. Zlib_readBitsFromStream (
  381. UINT32 *bitp,
  382. const UINT8 *bits,
  383. UINT32 nbits
  384. )
  385. {
  386. UINT32 i, result = 0;
  387. for (i = 0; i < nbits; i++)
  388. result += (Zlib_readBitFromStream (bitp, bits)) << i;
  389. return result;
  390. }
  391. VOID
  392. Inflator_generateFixedTrees (
  393. HuffmanTree * tree,
  394. HuffmanTree * treeD
  395. )
  396. { // get the tree of a deflated block with fixed tree
  397. UINT32 i;
  398. vector32_t *bitlen, *bitlenD;
  399. bitlen = vector32_new (288, 8);
  400. bitlenD = vector32_new (32, 5);
  401. for (i = 144; i <= 255; i++)
  402. bitlen->data[i] = 9;
  403. for (i = 256; i <= 279; i++)
  404. bitlen->data[i] = 7;
  405. HuffmanTree_makeFromLengths (tree, bitlen, 15);
  406. HuffmanTree_makeFromLengths (treeD, bitlenD, 15);
  407. }
  408. UINT32
  409. Inflator_huffmanDecodeSymbol (
  410. const UINT8 *in,
  411. UINT32 *bp,
  412. const HuffmanTree * codetree,
  413. UINT32 inlength
  414. )
  415. { // decode a single symbol from given list of bits with given code tree. returns the symbol
  416. BOOLEAN decoded = FALSE;
  417. UINT32 ct = 0;
  418. UINT32 treepos = 0;
  419. for (;;) {
  420. if ((*bp & 0x07) == 0 && (*bp >> 3) > inlength) {
  421. Inflator_error = 10; // error: end reached without endcode
  422. return 0;
  423. }
  424. Inflator_error =
  425. HuffmanTree_decode (codetree, &decoded, &ct, &treepos,
  426. Zlib_readBitFromStream (bp, in));
  427. if (Inflator_error)
  428. return 0; // stop, an error happened
  429. if (decoded)
  430. return ct;
  431. }
  432. }
  433. VOID
  434. Inflator_getTreeInflateDynamic (
  435. HuffmanTree * tree,
  436. HuffmanTree * treeD,
  437. const UINT8 *in,
  438. UINT32 *bp,
  439. UINT32 inlength
  440. )
  441. { // get the tree of a deflated block with dynamic tree, the tree itself is also Huffman
  442. // compressed with a known tree
  443. UINT32 i, n;
  444. HuffmanTree *codelengthcodetree = HuffmanTree_new (); // the code tree for code length codes
  445. vector32_t *bitlen, *bitlenD;
  446. UINT32 HLIT; // number of literal/length codes + 257
  447. UINT32 HDIST; // number of dist codes + 1
  448. UINT32 HCLEN; // number of code length codes + 4
  449. vector32_t *codelengthcode; // lengths of tree to decode the lengths of the dynamic tree
  450. UINT32 replength;
  451. bitlen = vector32_new (288, 0);
  452. bitlenD = vector32_new (32, 0);
  453. if (*bp >> 3 >= inlength - 2) {
  454. Inflator_error = 49; // the bit pointer is or will go past the memory
  455. return;
  456. }
  457. HLIT = Zlib_readBitsFromStream (bp, in, 5) + 257; // number of literal/length codes + 257
  458. HDIST = Zlib_readBitsFromStream (bp, in, 5) + 1; // number of dist codes + 1
  459. HCLEN = Zlib_readBitsFromStream (bp, in, 4) + 4; // number of code length codes + 4
  460. codelengthcode = vector32_new (19, 0);
  461. for (i = 0; i < 19; i++)
  462. codelengthcode->data[CLCL[i]] =
  463. (i < HCLEN) ? Zlib_readBitsFromStream (bp, in, 3) : 0;
  464. Inflator_error =
  465. HuffmanTree_makeFromLengths (codelengthcodetree, codelengthcode, 7);
  466. if (Inflator_error)
  467. return;
  468. for (i = 0; i < HLIT + HDIST;) {
  469. UINT32 code =
  470. Inflator_huffmanDecodeSymbol (in, bp, codelengthcodetree, inlength);
  471. if (Inflator_error)
  472. return;
  473. if (code <= 15) { // a length code
  474. if (i < HLIT)
  475. bitlen->data[i++] = code;
  476. else
  477. bitlenD->data[i++ - HLIT] = code;
  478. }
  479. else if (code == 16) { // repeat previous
  480. UINT32 value; // set value to the previous code
  481. if (*bp >> 3 >= inlength) {
  482. Inflator_error = 50; // error, bit pointer jumps past memory
  483. return;
  484. }
  485. replength = 3 + Zlib_readBitsFromStream (bp, in, 2);
  486. if ((i - 1) < HLIT)
  487. value = bitlen->data[i - 1];
  488. else
  489. value = bitlenD->data[i - HLIT - 1];
  490. for (n = 0; n < replength; n++) { // repeat this value in the next lengths
  491. if (i >= HLIT + HDIST) {
  492. Inflator_error = 13; // error: i is larger than the amount of codes
  493. return;
  494. }
  495. if (i < HLIT)
  496. bitlen->data[i++] = value;
  497. else
  498. bitlenD->data[i++ - HLIT] = value;
  499. }
  500. }
  501. else if (code == 17) { // repeat "0" 3-10 times
  502. if (*bp >> 3 >= inlength) {
  503. Inflator_error = 50; // error, bit pointer jumps past memory
  504. return;
  505. }
  506. replength = 3 + Zlib_readBitsFromStream (bp, in, 3);
  507. for (n = 0; n < replength; n++) { // repeat this value in the next lengths
  508. if (i >= HLIT + HDIST) {
  509. Inflator_error = 14; // error: i is larger than the amount of codes
  510. return;
  511. }
  512. if (i < HLIT)
  513. bitlen->data[i++] = 0;
  514. else
  515. bitlenD->data[i++ - HLIT] = 0;
  516. }
  517. }
  518. else if (code == 18) { // repeat "0" 11-138 times
  519. if (*bp >> 3 >= inlength) {
  520. Inflator_error = 50; // error, bit pointer jumps past memory
  521. return;
  522. }
  523. replength = 11 + Zlib_readBitsFromStream (bp, in, 7);
  524. for (n = 0; n < replength; n++) { // repeat this value in the next lengths
  525. if (i >= HLIT + HDIST) {
  526. Inflator_error = 15; // error: i is larger than the amount of codes
  527. return;
  528. }
  529. if (i < HLIT)
  530. bitlen->data[i++] = 0;
  531. else
  532. bitlenD->data[i++ - HLIT] = 0;
  533. }
  534. }
  535. else {
  536. Inflator_error = 16; // error: an nonexitent code appeared. This can never happen.
  537. return;
  538. }
  539. }
  540. if (bitlen->data[256] == 0) {
  541. Inflator_error = 64; // the length of the end code 256 must be larger than 0
  542. return;
  543. }
  544. // now we've finally got HLIT and HDIST, so generate the code trees, and the function is done
  545. Inflator_error = HuffmanTree_makeFromLengths (tree, bitlen, 15);
  546. if (Inflator_error)
  547. return;
  548. Inflator_error = HuffmanTree_makeFromLengths (treeD, bitlenD, 15);
  549. if (Inflator_error)
  550. return;
  551. }
  552. VOID
  553. Inflator_inflateHuffmanBlock (
  554. vector8_t * out,
  555. const UINT8 *in,
  556. UINT32 *bp,
  557. UINT32 *pos,
  558. UINT32 inlength,
  559. UINT32 btype
  560. )
  561. {
  562. HuffmanTree *codetree, *codetreeD; // the code tree for Huffman codes, dist codes
  563. codetree = HuffmanTree_new ();
  564. codetreeD = HuffmanTree_new ();
  565. if (btype == 1)
  566. Inflator_generateFixedTrees (codetree, codetreeD);
  567. else if (btype == 2) {
  568. Inflator_getTreeInflateDynamic (codetree, codetreeD, in, bp, inlength);
  569. if (Inflator_error)
  570. return;
  571. }
  572. for (;;) {
  573. UINT32 code = Inflator_huffmanDecodeSymbol (in, bp, codetree, inlength);
  574. if (Inflator_error)
  575. return;
  576. if (code == 256) // end code
  577. return;
  578. else if (code <= 255) { // literal symbol
  579. if (*pos >= out->size)
  580. vector8_resize (out, (*pos + 1) * 2); // reserve more room
  581. out->data[(*pos)++] = (UINT8) code;
  582. }
  583. else if (code >= 257 && code <= 285) { // length code
  584. UINT32 codeD;
  585. UINT32 dist;
  586. UINT32 numextrabitsD;
  587. UINT32 start;
  588. UINT32 back;
  589. UINT32 i;
  590. UINT32 length = LENBASE[code - 257], numextrabits = LENEXTRA[code - 257];
  591. if ((*bp >> 3) >= inlength) {
  592. Inflator_error = 51; // error, bit pointer will jump past memory
  593. return;
  594. }
  595. length += Zlib_readBitsFromStream (bp, in, numextrabits);
  596. codeD = Inflator_huffmanDecodeSymbol (in, bp, codetreeD, inlength);
  597. if (Inflator_error)
  598. return;
  599. if (codeD > 29) {
  600. Inflator_error = 18; // error: invalid dist code (30-31 are never used)
  601. return;
  602. }
  603. dist = DISTBASE[codeD];
  604. numextrabitsD = DISTEXTRA[codeD];
  605. if ((*bp >> 3) >= inlength) {
  606. Inflator_error = 51; // error, bit pointer will jump past memory
  607. return;
  608. }
  609. dist += Zlib_readBitsFromStream (bp, in, numextrabitsD);
  610. start = *pos;
  611. back = start - dist; // backwards
  612. if (*pos + length >= out->size)
  613. vector8_resize (out, (*pos + length) * 2); // reserve more room
  614. for (i = 0; i < length; i++) {
  615. out->data[(*pos)++] = out->data[back++];
  616. if (back >= start)
  617. back = start - dist;
  618. }
  619. }
  620. }
  621. }
  622. VOID
  623. Inflator_inflateNoCompression (
  624. vector8_t * out,
  625. const UINT8 *in,
  626. UINT32 *bp,
  627. UINT32 *pos,
  628. UINT32 inlength
  629. )
  630. {
  631. UINT32 p;
  632. UINT32 n;
  633. UINT32 LEN;
  634. UINT32 NLEN;
  635. while ((*bp & 0x7) != 0)
  636. (*bp)++; // go to first boundary of byte
  637. p = *bp / 8;
  638. if (p >= inlength - 4) {
  639. Inflator_error = 52; // error, bit pointer will jump past memory
  640. return;
  641. }
  642. LEN = in[p] + 256 * in[p + 1];
  643. NLEN = in[p + 2] + 256 * in[p + 3];
  644. p += 4;
  645. if (LEN + NLEN != 65535) {
  646. Inflator_error = 21; // error: NLEN is not one's complement of LEN
  647. return;
  648. }
  649. if (*pos + LEN >= out->size)
  650. vector8_resize (out, *pos + LEN);
  651. if (p + LEN > inlength) {
  652. Inflator_error = 23; // error: reading outside of in buffer
  653. return;
  654. }
  655. for (n = 0; n < LEN; n++)
  656. out->data[(*pos)++] = in[p++]; // read LEN bytes of literal data
  657. *bp = p * 8;
  658. }
  659. VOID
  660. Inflator_inflate (
  661. vector8_t * out,
  662. const vector8_t * in,
  663. UINT32 inpos
  664. )
  665. {
  666. UINT32 bp = 0, pos = 0; // bit pointer and byte pointer
  667. UINT32 BFINAL = 0;
  668. Inflator_error = 0;
  669. while (!BFINAL && !Inflator_error) {
  670. UINT32 BTYPE;
  671. if (bp >> 3 >= in->size) {
  672. Inflator_error = 52; // error, bit pointer will jump past memory
  673. return;
  674. }
  675. BFINAL = Zlib_readBitFromStream (&bp, &in->data[inpos]);
  676. BTYPE = Zlib_readBitFromStream (&bp, &in->data[inpos]);
  677. BTYPE += 2 * Zlib_readBitFromStream (&bp, &in->data[inpos]);
  678. if (BTYPE == 3) {
  679. Inflator_error = 20; // error: invalid BTYPE
  680. return;
  681. }
  682. else if (BTYPE == 0)
  683. Inflator_inflateNoCompression (out, &in->data[inpos], &bp, &pos,
  684. in->size);
  685. else
  686. Inflator_inflateHuffmanBlock (out, &in->data[inpos], &bp, &pos, in->size,
  687. BTYPE);
  688. }
  689. if (!Inflator_error)
  690. vector8_resize (out, pos); // Only now we know the true size of out, resize it to that
  691. }
  692. /*************************************************************************************************/
  693. UINT8
  694. Zlib_decompress (
  695. vector8_t * out,
  696. const vector8_t * in
  697. ) // returns error value
  698. {
  699. UINT32 CM, CINFO, FDICT;
  700. if (in->size < 2)
  701. return 53; // error, size of zlib data too small
  702. if ((in->data[0] * 256 + in->data[1]) % 31 != 0)
  703. // error: 256 * in->data[0] + in->data[1] must be a multiple of 31, the FCHECK value is
  704. // supposed to be made that way
  705. return 24;
  706. CM = in->data[0] & 15;
  707. CINFO = (in->data[0] >> 4) & 15;
  708. FDICT = (in->data[1] >> 5) & 1;
  709. if (CM != 8 || CINFO > 7)
  710. // error: only compression method 8: inflate with sliding window of 32k is supported by
  711. // the PNG spec
  712. return 25;
  713. if (FDICT != 0)
  714. // error: the specification of PNG says about the zlib stream: "The additional flags shall
  715. // not specify a preset dictionary."
  716. return 26;
  717. Inflator_inflate (out, in, 2);
  718. return (UINT8) Inflator_error; // note: adler32 checksum was skipped and ignored
  719. }
  720. /*************************************************************************************************/
  721. #define PNG_SIGNATURE 0x0a1a0a0d474e5089ull
  722. #define CHUNK_IHDR 0x52444849
  723. #define CHUNK_IDAT 0x54414449
  724. #define CHUNK_IEND 0x444e4549
  725. #define CHUNK_PLTE 0x45544c50
  726. #define CHUNK_tRNS 0x534e5274
  727. UINT8 PNG_error;
  728. UINT32
  729. PNG_readBitFromReversedStream (
  730. UINT32 *bitp,
  731. const UINT8 *bits
  732. )
  733. {
  734. UINT32 result = (bits[*bitp >> 3] >> (7 - (*bitp & 0x7))) & 1;
  735. (*bitp)++;
  736. return result;
  737. }
  738. UINT32
  739. PNG_readBitsFromReversedStream (
  740. UINT32 *bitp,
  741. const UINT8 *bits,
  742. UINT32 nbits
  743. )
  744. {
  745. UINT32 i, result = 0;
  746. for (i = nbits - 1; i < nbits; i--)
  747. result += ((PNG_readBitFromReversedStream (bitp, bits)) << i);
  748. return result;
  749. }
  750. VOID
  751. PNG_setBitOfReversedStream (
  752. UINT32 *bitp,
  753. UINT8 *bits,
  754. UINT32 bit
  755. )
  756. {
  757. bits[*bitp >> 3] |= (bit << (7 - (*bitp & 0x7)));
  758. (*bitp)++;
  759. }
  760. UINT32
  761. PNG_read32bitInt (
  762. const UINT8 *buffer
  763. )
  764. {
  765. return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
  766. }
  767. UINT8
  768. PNG_checkColorValidity (
  769. UINT32 colorType,
  770. UINT32 bd
  771. ) // return type is a LodePNG error code
  772. {
  773. if ((colorType == 2 || colorType == 4 || colorType == 6)) {
  774. if (!(bd == 8 || bd == 16))
  775. return 37;
  776. else
  777. return 0;
  778. }
  779. else if (colorType == 0) {
  780. if (!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16))
  781. return 37;
  782. else
  783. return 0;
  784. }
  785. else if (colorType == 3) {
  786. if (!(bd == 1 || bd == 2 || bd == 4 || bd == 8))
  787. return 37;
  788. else
  789. return 0;
  790. }
  791. else
  792. return 31; // nonexistent color type
  793. }
  794. UINT32
  795. PNG_getBpp (
  796. const PNG_info_t * info
  797. )
  798. {
  799. UINT32 bitDepth, colorType;
  800. bitDepth = info->bitDepth;
  801. colorType = info->colorType;
  802. if (colorType == 2)
  803. return (3 * bitDepth);
  804. else if (colorType >= 4)
  805. return (colorType - 2) * bitDepth;
  806. else
  807. return bitDepth;
  808. }
  809. VOID
  810. PNG_readPngHeader (
  811. PNG_info_t * info,
  812. const UINT8 *in,
  813. UINT32 inlength
  814. )
  815. { // read the information from the header and store it in the Info
  816. if (inlength < 29) {
  817. PNG_error = 27; // error: the data length is smaller than the length of the header
  818. return;
  819. }
  820. if (*(UINT64 *) in != PNG_SIGNATURE) {
  821. PNG_error = 28; // no PNG signature
  822. return;
  823. }
  824. if (*(UINT32 *) &in[12] != CHUNK_IHDR) {
  825. PNG_error = 29; // error: it doesn't start with a IHDR chunk!
  826. return;
  827. }
  828. info->width = PNG_read32bitInt (&in[16]);
  829. info->height = PNG_read32bitInt (&in[20]);
  830. info->bitDepth = in[24];
  831. info->colorType = in[25];
  832. info->compressionMethod = in[26];
  833. if (in[26] != 0) {
  834. PNG_error = 32; // error: only compression method 0 is allowed in the specification
  835. return;
  836. }
  837. info->filterMethod = in[27];
  838. if (in[27] != 0) {
  839. PNG_error = 33; // error: only filter method 0 is allowed in the specification
  840. return;
  841. }
  842. info->interlaceMethod = in[28];
  843. if (in[28] > 1) {
  844. PNG_error = 34; // error: only interlace methods 0 and 1 exist in the specification
  845. return;
  846. }
  847. PNG_error = PNG_checkColorValidity (info->colorType, info->bitDepth);
  848. }
  849. int
  850. PNG_paethPredictor (
  851. int a,
  852. int b,
  853. int c
  854. ) // Paeth predicter, used by PNG filter type 4
  855. {
  856. int p, pa, pb, pc;
  857. p = a + b - c;
  858. pa = p > a ? (p - a) : (a - p);
  859. pb = p > b ? (p - b) : (b - p);
  860. pc = p > c ? (p - c) : (c - p);
  861. return (pa <= pb && pa <= pc) ? a : (pb <= pc ? b : c);
  862. }
  863. VOID
  864. PNG_unFilterScanline (
  865. UINT8 *recon,
  866. const UINT8 *scanline,
  867. const UINT8 *precon,
  868. UINT32 bytewidth,
  869. UINT32 filterType,
  870. UINT32 length
  871. )
  872. {
  873. UINT32 i;
  874. switch (filterType) {
  875. case 0:
  876. for (i = 0; i < length; i++)
  877. recon[i] = scanline[i];
  878. break;
  879. case 1:
  880. for (i = 0; i < bytewidth; i++)
  881. recon[i] = scanline[i];
  882. for (i = bytewidth; i < length; i++)
  883. recon[i] = scanline[i] + recon[i - bytewidth];
  884. break;
  885. case 2:
  886. if (precon)
  887. for (i = 0; i < length; i++)
  888. recon[i] = scanline[i] + precon[i];
  889. else
  890. for (i = 0; i < length; i++)
  891. recon[i] = scanline[i];
  892. break;
  893. case 3:
  894. if (precon) {
  895. for (i = 0; i < bytewidth; i++)
  896. recon[i] = scanline[i] + precon[i] / 2;
  897. for (i = bytewidth; i < length; i++)
  898. recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2);
  899. }
  900. else {
  901. for (i = 0; i < bytewidth; i++)
  902. recon[i] = scanline[i];
  903. for (i = bytewidth; i < length; i++)
  904. recon[i] = scanline[i] + recon[i - bytewidth] / 2;
  905. }
  906. break;
  907. case 4:
  908. if (precon) {
  909. for (i = 0; i < bytewidth; i++)
  910. recon[i] = (UINT8) (scanline[i] + PNG_paethPredictor (0, precon[i], 0));
  911. for (i = bytewidth; i < length; i++)
  912. recon[i] =
  913. (UINT8) (scanline[i] +
  914. PNG_paethPredictor (recon[i - bytewidth], precon[i],
  915. precon[i - bytewidth]));
  916. }
  917. else {
  918. for (i = 0; i < bytewidth; i++)
  919. recon[i] = scanline[i];
  920. for (i = bytewidth; i < length; i++)
  921. recon[i] =
  922. (UINT8) (scanline[i] +
  923. PNG_paethPredictor (recon[i - bytewidth], 0, 0));
  924. }
  925. break;
  926. default:
  927. PNG_error = 36; // error: nonexistent filter type given
  928. return;
  929. }
  930. }
  931. VOID
  932. PNG_adam7Pass (
  933. UINT8 *out,
  934. UINT8 *linen,
  935. UINT8 *lineo,
  936. const UINT8 *in,
  937. UINT32 w,
  938. UINT32 passleft,
  939. UINT32 passtop,
  940. UINT32 spacex,
  941. UINT32 spacey,
  942. UINT32 passw,
  943. UINT32 passh,
  944. UINT32 bpp
  945. )
  946. { // filter and reposition the pixels into the output when the image is Adam7 interlaced. This
  947. // function can only do it after the full image is already decoded. The out buffer must have
  948. // the correct allocated memory size already.
  949. UINT32 bytewidth, linelength;
  950. UINT32 y;
  951. UINT8 *temp;
  952. if (passw == 0)
  953. return;
  954. bytewidth = (bpp + 7) / 8;
  955. linelength = 1 + ((bpp * passw + 7) / 8);
  956. for (y = 0; y < passh; y++) {
  957. UINT32 i, b;
  958. UINT8 filterType = in[y * linelength], *prevline = (y == 0) ? 0 : lineo;
  959. PNG_unFilterScanline (linen, &in[y * linelength + 1], prevline, bytewidth,
  960. filterType, (w * bpp + 7) / 8);
  961. if (PNG_error)
  962. return;
  963. if (bpp >= 8)
  964. for (i = 0; i < passw; i++)
  965. for (b = 0; b < bytewidth; b++) // b = current byte of this pixel
  966. out[bytewidth * w * (passtop + spacey * y) +
  967. bytewidth * (passleft + spacex * i) + b] =
  968. linen[bytewidth * i + b];
  969. else
  970. for (i = 0; i < passw; i++) {
  971. UINT32 obp, bp;
  972. obp = bpp * w * (passtop + spacey * y) + bpp * (passleft + spacex * i);
  973. bp = i * bpp;
  974. for (b = 0; b < bpp; b++)
  975. PNG_setBitOfReversedStream (&obp, out,
  976. PNG_readBitFromReversedStream (&bp,
  977. linen));
  978. }
  979. temp = linen;
  980. linen = lineo;
  981. lineo = temp; // swap the two buffer pointers "line old" and "line new"
  982. }
  983. }
  984. UINT8
  985. PNG_convert (
  986. const PNG_info_t * info,
  987. vector8_t * out,
  988. const UINT8 *in
  989. )
  990. { // converts from any color type to 32-bit. return value = LodePNG error code
  991. UINT32 i, c;
  992. UINT32 bitDepth, colorType;
  993. UINT32 numpixels, bp;
  994. UINT8 *out_data = out->size ? out->data : 0;
  995. bitDepth = info->bitDepth;
  996. colorType = info->colorType;
  997. numpixels = info->width * info->height;
  998. bp = 0;
  999. vector8_resize (out, numpixels * 4);
  1000. if (bitDepth == 8 && colorType == 0) // greyscale
  1001. for (i = 0; i < numpixels; i++) {
  1002. out_data[4 * i + 0] = out_data[4 * i + 1] = out_data[4 * i + 2] = in[i];
  1003. out_data[4 * i + 3] = (info->key_defined &&
  1004. (in[i] == info->key_r)) ? 0 : 255;
  1005. }
  1006. else if (bitDepth == 8 && colorType == 2) // RGB color
  1007. for (i = 0; i < numpixels; i++) {
  1008. for (c = 0; c < 3; c++)
  1009. out_data[4 * i + c] = in[3 * i + c];
  1010. out_data[4 * i + 3] = (info->key_defined && (in[3 * i + 0] == info->key_r)
  1011. && (in[3 * i + 1] == info->key_g) &&
  1012. (in[3 * i + 2] == info->key_b)) ? 0 : 255;
  1013. }
  1014. else if (bitDepth == 8 && colorType == 3) // indexed color (palette)
  1015. for (i = 0; i < numpixels; i++) {
  1016. if (4U * in[i] >= info->palette->size)
  1017. return 46;
  1018. for (c = 0; c < 4; c++) // get rgb colors from the palette
  1019. out_data[4 * i + c] = info->palette->data[4 * in[i] + c];
  1020. }
  1021. else if (bitDepth == 8 && colorType == 4) // greyscale with alpha
  1022. for (i = 0; i < numpixels; i++) {
  1023. out_data[4 * i + 0] = out_data[4 * i + 1] = out_data[4 * i + 2] =
  1024. in[2 * i + 0];
  1025. out_data[4 * i + 3] = in[2 * i + 1];
  1026. }
  1027. else if (bitDepth == 8 && colorType == 6)
  1028. for (i = 0; i < numpixels; i++)
  1029. for (c = 0; c < 4; c++)
  1030. out_data[4 * i + c] = in[4 * i + c]; // RGB with alpha
  1031. else if (bitDepth == 16 && colorType == 0) // greyscale
  1032. for (i = 0; i < numpixels; i++) {
  1033. out_data[4 * i + 0] = out_data[4 * i + 1] = out_data[4 * i + 2] =
  1034. in[2 * i];
  1035. out_data[4 * i + 3] = (info->key_defined &&
  1036. (256U * in[i] + in[i + 1] == info->key_r))
  1037. ? 0 : 255;
  1038. }
  1039. else if (bitDepth == 16 && colorType == 2) // RGB color
  1040. for (i = 0; i < numpixels; i++) {
  1041. for (c = 0; c < 3; c++)
  1042. out_data[4 * i + c] = in[6 * i + 2 * c];
  1043. out_data[4 * i + 3] = (info->key_defined &&
  1044. (256U * in[6 * i + 0] + in[6 * i + 1] ==
  1045. info->key_r) &&
  1046. (256U * in[6 * i + 2] + in[6 * i + 3] ==
  1047. info->key_g) &&
  1048. (256U * in[6 * i + 4] + in[6 * i + 5] ==
  1049. info->key_b)) ? 0 : 255;
  1050. }
  1051. else if (bitDepth == 16 && colorType == 4) // greyscale with alpha
  1052. for (i = 0; i < numpixels; i++) {
  1053. out_data[4 * i + 0] = out_data[4 * i + 1] = out_data[4 * i + 2] = in[4 * i]; // msb
  1054. out_data[4 * i + 3] = in[4 * i + 2];
  1055. }
  1056. else if (bitDepth == 16 && colorType == 6)
  1057. for (i = 0; i < numpixels; i++)
  1058. for (c = 0; c < 4; c++)
  1059. out_data[4 * i + c] = in[8 * i + 2 * c]; // RGB with alpha
  1060. else if (bitDepth < 8 && colorType == 0) // greyscale
  1061. for (i = 0; i < numpixels; i++) {
  1062. UINT32 value = (PNG_readBitsFromReversedStream (&bp, in, bitDepth) * 255) / ((1 << bitDepth) - 1); // scale value from 0 to 255
  1063. out_data[4 * i + 0] = out_data[4 * i + 1] = out_data[4 * i + 2] =
  1064. (UINT8) value;
  1065. out_data[4 * i + 3] = (info->key_defined && value &&
  1066. (((1U << bitDepth) - 1U) == info->key_r) &&
  1067. ((1U << bitDepth) - 1U)) ? 0 : 255;
  1068. }
  1069. else if (bitDepth < 8 && colorType == 3) // palette
  1070. for (i = 0; i < numpixels; i++) {
  1071. UINT32 value = PNG_readBitsFromReversedStream (&bp, in, bitDepth);
  1072. if (4 * value >= info->palette->size)
  1073. return 47;
  1074. for (c = 0; c < 4; c++) // get rgb colors from the palette
  1075. out_data[4 * i + c] = info->palette->data[4 * value + c];
  1076. }
  1077. return 0;
  1078. }
  1079. PNG_info_t *
  1080. PNG_info_new (
  1081. )
  1082. {
  1083. PNG_info_t *info;
  1084. info = png_alloc_malloc (sizeof (PNG_info_t));
  1085. #if 0
  1086. for (i = 0; i < sizeof (PNG_info_t); i++)
  1087. ((UINT8 *) info)[i] = 0;
  1088. #endif
  1089. info->palette = vector8_new (0, 0);
  1090. info->image = vector8_new (0, 0);
  1091. return info;
  1092. }
  1093. PNG_info_t *
  1094. PNG_decode (
  1095. const UINT8 *in,
  1096. UINT32 size
  1097. )
  1098. {
  1099. PNG_info_t *info;
  1100. UINT32 pos; // first byte of the first chunk after the header
  1101. vector8_t *idat; // the data from idat chunks
  1102. BOOLEAN IEND, known_type;
  1103. UINT32 bpp;
  1104. vector8_t *scanlines; // now the out buffer will be filled
  1105. UINT32 bytewidth, outlength;
  1106. UINT8 *out_data;
  1107. PNG_error = 0;
  1108. if (size == 0 || in == 0) {
  1109. PNG_error = 48; // the given data is empty
  1110. return NULL;
  1111. }
  1112. info = PNG_info_new ();
  1113. PNG_readPngHeader (info, in, size);
  1114. if (PNG_error)
  1115. return NULL;
  1116. pos = 33; // first byte of the first chunk after the header
  1117. idat = NULL; // the data from idat chunks
  1118. IEND = FALSE;
  1119. known_type = TRUE;
  1120. info->key_defined = FALSE;
  1121. // loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is
  1122. // put at the start of the in buffer
  1123. while (!IEND) {
  1124. UINT32 i, j;
  1125. UINT32 chunkLength;
  1126. UINT32 chunkType;
  1127. if (pos + 8 >= size) {
  1128. PNG_error = 30; // error: size of the in buffer too small to contain next chunk
  1129. return NULL;
  1130. }
  1131. chunkLength = PNG_read32bitInt (&in[pos]);
  1132. pos += 4;
  1133. if (chunkLength > 0x7fffffff) {
  1134. PNG_error = 63;
  1135. return NULL;
  1136. }
  1137. if (pos + chunkLength >= size) {
  1138. PNG_error = 35; // error: size of the in buffer too small to contain next chunk
  1139. return NULL;
  1140. }
  1141. chunkType = *(UINT32 *) &in[pos];
  1142. if (chunkType == CHUNK_IDAT) { // IDAT: compressed image data chunk
  1143. UINT32 offset = 0;
  1144. if (idat) {
  1145. offset = idat->size;
  1146. vector8_resize (idat, offset + chunkLength);
  1147. }
  1148. else
  1149. idat = vector8_new (chunkLength, 0);
  1150. for (i = 0; i < chunkLength; i++)
  1151. idat->data[offset + i] = in[pos + 4 + i];
  1152. pos += (4 + chunkLength);
  1153. }
  1154. else if (chunkType == CHUNK_IEND) { // IEND
  1155. pos += 4;
  1156. IEND = TRUE;
  1157. }
  1158. else if (chunkType == CHUNK_PLTE) { // PLTE: palette chunk
  1159. pos += 4; // go after the 4 letters
  1160. vector8_resize (info->palette, 4 * (chunkLength / 3));
  1161. if (info->palette->size > (4 * 256)) {
  1162. PNG_error = 38; // error: palette too big
  1163. return NULL;
  1164. }
  1165. for (i = 0; i < info->palette->size; i += 4) {
  1166. for (j = 0; j < 3; j++)
  1167. info->palette->data[i + j] = in[pos++]; // RGB
  1168. info->palette->data[i + 3] = 255; // alpha
  1169. }
  1170. }
  1171. else if (chunkType == CHUNK_tRNS) { // tRNS: palette transparency chunk
  1172. pos += 4; // go after the 4 letters
  1173. if (info->colorType == 3) {
  1174. if (4 * chunkLength > info->palette->size) {
  1175. PNG_error = 39; // error: more alpha values given than there are palette entries
  1176. return NULL;
  1177. }
  1178. for (i = 0; i < chunkLength; i++)
  1179. info->palette->data[4 * i + 3] = in[pos++];
  1180. }
  1181. else if (info->colorType == 0) {
  1182. if (chunkLength != 2) {
  1183. PNG_error = 40; // error: this chunk must be 2 bytes for greyscale image
  1184. return NULL;
  1185. }
  1186. info->key_defined = TRUE;
  1187. info->key_r = info->key_g = info->key_b = 256 * in[pos] + in[pos + 1];
  1188. pos += 2;
  1189. }
  1190. else if (info->colorType == 2) {
  1191. if (chunkLength != 6) {
  1192. PNG_error = 41; // error: this chunk must be 6 bytes for RGB image
  1193. return NULL;
  1194. }
  1195. info->key_defined = TRUE;
  1196. info->key_r = 256 * in[pos] + in[pos + 1];
  1197. pos += 2;
  1198. info->key_g = 256 * in[pos] + in[pos + 1];
  1199. pos += 2;
  1200. info->key_b = 256 * in[pos] + in[pos + 1];
  1201. pos += 2;
  1202. }
  1203. else {
  1204. PNG_error = 42; // error: tRNS chunk not allowed for other color models
  1205. return NULL;
  1206. }
  1207. }
  1208. else { // it's not an implemented chunk type, so ignore it: skip over the data
  1209. if (!(in[pos + 0] & 32)) {
  1210. // error: unknown critical chunk (5th bit of first byte of chunk type is 0)
  1211. PNG_error = 69;
  1212. return NULL;
  1213. }
  1214. pos += (chunkLength + 4); // skip 4 letters and uninterpreted data of unimplemented chunk
  1215. known_type = FALSE;
  1216. }
  1217. pos += 4; // step over CRC (which is ignored)
  1218. }
  1219. bpp = PNG_getBpp (info);
  1220. scanlines =
  1221. vector8_new (((info->width * (info->height * bpp + 7)) / 8) + info->height,
  1222. 0);
  1223. PNG_error = Zlib_decompress (scanlines, idat);
  1224. if (PNG_error)
  1225. return NULL; // stop if the zlib decompressor returned an error
  1226. bytewidth = (bpp + 7) / 8;
  1227. outlength = (info->height * info->width * bpp + 7) / 8;
  1228. vector8_resize (info->image, outlength); // time to fill the out buffer
  1229. out_data = outlength ? info->image->data : 0;
  1230. if (info->interlaceMethod == 0) { // no interlace, just filter
  1231. UINT32 y, obp, bp;
  1232. UINT32 linestart, linelength;
  1233. linestart = 0;
  1234. // length in bytes of a scanline, excluding the filtertype byte
  1235. linelength = (info->width * bpp + 7) / 8;
  1236. if (bpp >= 8) // byte per byte
  1237. for (y = 0; y < info->height; y++) {
  1238. UINT32 filterType = scanlines->data[linestart];
  1239. const UINT8 *prevline;
  1240. prevline = (y == 0) ? 0 : &out_data[(y - 1) * info->width * bytewidth];
  1241. PNG_unFilterScanline (&out_data[linestart - y],
  1242. &scanlines->data[linestart + 1], prevline,
  1243. bytewidth, filterType, linelength);
  1244. if (PNG_error)
  1245. return NULL;
  1246. linestart += (1 + linelength); // go to start of next scanline
  1247. }
  1248. else { // less than 8 bits per pixel, so fill it up bit per bit
  1249. vector8_t *templine; // only used if bpp < 8
  1250. templine = vector8_new ((info->width * bpp + 7) >> 3, 0);
  1251. for (y = 0, obp = 0; y < info->height; y++) {
  1252. UINT32 filterType = scanlines->data[linestart];
  1253. const UINT8 *prevline;
  1254. prevline = (y == 0) ? 0 : &out_data[(y - 1) * info->width * bytewidth];
  1255. PNG_unFilterScanline (templine->data, &scanlines->data[linestart + 1],
  1256. prevline, bytewidth, filterType, linelength);
  1257. if (PNG_error)
  1258. return NULL;
  1259. for (bp = 0; bp < info->width * bpp;)
  1260. PNG_setBitOfReversedStream (&obp, out_data,
  1261. PNG_readBitFromReversedStream (&bp,
  1262. templine->
  1263. data));
  1264. linestart += (1 + linelength); // go to start of next scanline
  1265. }
  1266. }
  1267. }
  1268. else { // interlaceMethod is 1 (Adam7)
  1269. int i;
  1270. vector8_t *scanlineo, *scanlinen; // "old" and "new" scanline
  1271. UINT32 passw[7] = {
  1272. (info->width + 7) / 8, (info->width + 3) / 8, (info->width + 3) / 4,
  1273. (info->width + 1) / 4, (info->width + 1) / 2, (info->width + 0) / 2,
  1274. (info->width + 0) / 1
  1275. };
  1276. UINT32 passh[7] = {
  1277. (info->height + 7) / 8, (info->height + 7) / 8, (info->height + 3) / 8,
  1278. (info->height + 3) / 4, (info->height + 1) / 4, (info->height + 1) / 2,
  1279. (info->height + 0) / 2
  1280. };
  1281. UINT32 passstart[7] = { 0, 0, 0, 0, 0, 0, 0 };
  1282. UINT32 pattern[28] =
  1283. { 0, 4, 0, 2, 0, 1, 0, 0, 0, 4, 0, 2, 0, 1, 8, 8, 4, 4, 2, 2, 1, 8, 8,
  1284. 8, 4, 4, 2, 2
  1285. }; // values for the adam7 passes
  1286. for (i = 0; i < 6; i++)
  1287. passstart[i + 1] =
  1288. passstart[i] + passh[i] * ((passw[i] ? 1 : 0) +
  1289. (passw[i] * bpp + 7) / 8);
  1290. scanlineo = vector8_new ((info->width * bpp + 7) / 8, 0);
  1291. scanlinen = vector8_new ((info->width * bpp + 7) / 8, 0);
  1292. for (i = 0; i < 7; i++)
  1293. PNG_adam7Pass (out_data, scanlinen->data, scanlineo->data,
  1294. &scanlines->data[passstart[i]], info->width, pattern[i],
  1295. pattern[i + 7], pattern[i + 14], pattern[i + 21], passw[i],
  1296. passh[i], bpp);
  1297. }
  1298. if (info->colorType != 6 || info->bitDepth != 8) { // conversion needed
  1299. vector8_t *copy = vector8_copy (info->image); // xxx: is this copy necessary?
  1300. PNG_error = PNG_convert (info, info->image, copy->data);
  1301. }
  1302. return info;
  1303. }
  1304. /*************************************************************************************************/
  1305. #ifdef TEST
  1306. #include <stdio.h>
  1307. #include <sys/stat.h>
  1308. int
  1309. main (
  1310. int argc,
  1311. char **argv
  1312. )
  1313. {
  1314. char *fname = (argc > 1) ? argv[1] : "test.png";
  1315. PNG_info_t *info;
  1316. struct stat statbuf;
  1317. UINT32 insize, outsize;
  1318. FILE *infp, *outfp;
  1319. UINT8 *inbuf;
  1320. UINT32 n;
  1321. if (stat (fname, &statbuf) != 0) {
  1322. perror ("stat");
  1323. return 1;
  1324. }
  1325. else if (!statbuf.st_size) {
  1326. printf ("file empty\n");
  1327. return 1;
  1328. }
  1329. insize = (UINT32) statbuf.st_size;
  1330. inbuf = png_alloc_malloc (insize);
  1331. infp = fopen (fname, "rb");
  1332. if (!infp) {
  1333. perror ("fopen");
  1334. png_alloc_free (inbuf);
  1335. return 1;
  1336. }
  1337. else if (fread (inbuf, 1, insize, infp) != insize) {
  1338. perror ("fread");
  1339. fclose (infp);
  1340. png_alloc_free (inbuf);
  1341. return 1;
  1342. }
  1343. fclose (infp);
  1344. printf ("input file: %s (size: %d)\n", fname, insize);
  1345. info = PNG_decode (inbuf, insize);
  1346. png_alloc_free (inbuf);
  1347. printf ("PNG_error: %d\n", PNG_error);
  1348. if (PNG_error != 0)
  1349. return 1;
  1350. printf ("width: %d, height: %d\nfirst 16 bytes: ", info->width, info->height);
  1351. for (n = 0; n < 16; n++)
  1352. printf ("%02x ", info->image->data[n]);
  1353. printf ("\n");
  1354. outsize = info->width * info->height * 4;
  1355. printf ("image size: %d\n", outsize);
  1356. if (outsize != info->image->size) {
  1357. printf ("error: image size doesn't match dimensions\n");
  1358. return 1;
  1359. }
  1360. outfp = fopen ("out.bin", "wb");
  1361. if (!outfp) {
  1362. perror ("fopen");
  1363. return 1;
  1364. }
  1365. else if (fwrite (info->image->data, 1, outsize, outfp) != outsize) {
  1366. perror ("fwrite");
  1367. return 1;
  1368. }
  1369. fclose (outfp);
  1370. #ifdef ALLOC_DEBUG
  1371. png_alloc_node_t *node;
  1372. for (node = png_alloc_head, n = 1; node; node = node->next, n++)
  1373. printf ("node %d (%p) addr = %p, size = %ld\n", n, node, node->addr,
  1374. node->size);
  1375. #endif
  1376. png_alloc_free_all (); // also frees info and image data from PNG_decode
  1377. return 0;
  1378. }
  1379. #endif