Advertisement
Guest User

Untitled

a guest
Feb 29th, 2016
536
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.46 KB | None | 0 0
  1. /* APNG Disassembler 2.5
  2. *
  3. * Deconstructs APNG files into individual frames.
  4. *
  5. * http://apngdis.sourceforge.net
  6. *
  7. * Copyright (c) 2010-2012 Max Stepin
  8. * maxst at users.sourceforge.net
  9. *
  10. * zlib license
  11. * ------------
  12. *
  13. * This software is provided 'as-is', without any express or implied
  14. * warranty. In no event will the authors be held liable for any damages
  15. * arising from the use of this software.
  16. *
  17. * Permission is granted to anyone to use this software for any purpose,
  18. * including commercial applications, and to alter it and redistribute it
  19. * freely, subject to the following restrictions:
  20. *
  21. * 1. The origin of this software must not be misrepresented; you must not
  22. * claim that you wrote the original software. If you use this software
  23. * in a product, an acknowledgment in the product documentation would be
  24. * appreciated but is not required.
  25. * 2. Altered source versions must be plainly marked as such, and must not be
  26. * misrepresented as being the original software.
  27. * 3. This notice may not be removed or altered from any source distribution.
  28. *
  29. */
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "zlib.h"
  34.  
  35. #if defined(_MSC_VER) && _MSC_VER >= 1300
  36. #define swap16(data) _byteswap_ushort(data)
  37. #define swap32(data) _byteswap_ulong(data)
  38. #elif defined(__linux__)
  39. #include <byteswap.h>
  40. #define swap16(data) bswap_16(data)
  41. #define swap32(data) bswap_32(data)
  42. #elif defined(__FreeBSD__)
  43. #include <sys/endian.h>
  44. #define swap16(data) bswap16(data)
  45. #define swap32(data) bswap32(data)
  46. #elif defined(__APPLE__)
  47. #include <libkern/OSByteOrder.h>
  48. #define swap16(data) OSSwapInt16(data)
  49. #define swap32(data) OSSwapInt32(data)
  50. #else
  51. unsigned short swap16(unsigned short data) {return((data & 0xFF) << 8) | ((data >> 8) & 0xFF);}
  52. unsigned int swap32(unsigned int data) {return((data & 0xFF) << 24) | ((data & 0xFF00) << 8) | ((data >> 8) & 0xFF00) | ((data >> 24) & 0xFF);}
  53. #endif
  54.  
  55. #define PNG_ZBUF_SIZE 32768
  56.  
  57. #define PNG_DISPOSE_OP_NONE 0x00
  58. #define PNG_DISPOSE_OP_BACKGROUND 0x01
  59. #define PNG_DISPOSE_OP_PREVIOUS 0x02
  60.  
  61. #define PNG_BLEND_OP_SOURCE 0x00
  62. #define PNG_BLEND_OP_OVER 0x01
  63.  
  64. #define notabc(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
  65.  
  66. #define ROWBYTES(pixel_bits, width) \
  67. ((pixel_bits) >= 8 ? \
  68. ((width) * (((unsigned int)(pixel_bits)) >> 3)) : \
  69. (( ((width) * ((unsigned int)(pixel_bits))) + 7) >> 3) )
  70.  
  71. unsigned char png_sign[8] = {137, 80, 78, 71, 13, 10, 26, 10};
  72. int mask4[2]={240,15};
  73. int shift4[2]={4,0};
  74. int mask2[4]={192,48,12,3};
  75. int shift2[4]={6,4,2,0};
  76. int mask1[8]={128,64,32,16,8,4,2,1};
  77. int shift1[8]={7,6,5,4,3,2,1,0};
  78. unsigned int keep_original = 1;
  79. unsigned char pal[256][3];
  80. unsigned char trns[256];
  81. unsigned int palsize, trnssize;
  82. unsigned short trns1, trns2, trns3;
  83. int trns_idx;
  84.  
  85. int read32(unsigned int *val, FILE * f1)
  86. {
  87. unsigned int res;
  88. if (fread(&res, 1, 4, f1) != 4) return 1;
  89. *val = swap32(res);
  90. return 0;
  91. }
  92.  
  93. int read16(unsigned short *val, FILE * f1)
  94. {
  95. unsigned short res;
  96. if (fread(&res, 1, 2, f1) != 2) return 1;
  97. *val = swap16(res);
  98. return 0;
  99. }
  100.  
  101. unsigned short readshort(unsigned char * p)
  102. {
  103. return ((unsigned short)(*p)<<8)+(unsigned short)(*(p+1));
  104. }
  105.  
  106. void read_sub_row(unsigned char * row, unsigned int rowbytes, unsigned int bpp)
  107. {
  108. unsigned int i;
  109.  
  110. for (i=bpp; i<rowbytes; i++)
  111. row[i] += row[i-bpp];
  112. }
  113.  
  114. void read_up_row(unsigned char * row, unsigned char * prev_row, unsigned int rowbytes, unsigned int bpp)
  115. {
  116. unsigned int i;
  117.  
  118. if (prev_row)
  119. for (i=0; i<rowbytes; i++)
  120. row[i] += prev_row[i];
  121. }
  122.  
  123. void read_average_row(unsigned char * row, unsigned char * prev_row, unsigned int rowbytes, unsigned int bpp)
  124. {
  125. unsigned int i;
  126.  
  127. if (prev_row)
  128. {
  129. for (i=0; i<bpp; i++)
  130. row[i] += prev_row[i]>>1;
  131. for (i=bpp; i<rowbytes; i++)
  132. row[i] += (prev_row[i] + row[i-bpp])>>1;
  133. }
  134. else
  135. {
  136. for (i=bpp; i<rowbytes; i++)
  137. row[i] += row[i-bpp]>>1;
  138. }
  139. }
  140.  
  141. void read_paeth_row(unsigned char * row, unsigned char * prev_row, unsigned int rowbytes, unsigned int bpp)
  142. {
  143. unsigned int i;
  144. int a, b, c, pa, pb, pc, p;
  145.  
  146. if (prev_row)
  147. {
  148. for (i=0; i<bpp; i++)
  149. row[i] += prev_row[i];
  150. for (i=bpp; i<rowbytes; i++)
  151. {
  152. a = row[i-bpp];
  153. b = prev_row[i];
  154. c = prev_row[i-bpp];
  155. p = b - c;
  156. pc = a - c;
  157. pa = abs(p);
  158. pb = abs(pc);
  159. pc = abs(p + pc);
  160. row[i] += ((pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c);
  161. }
  162. }
  163. else
  164. {
  165. for (i=bpp; i<rowbytes; i++)
  166. row[i] += row[i-bpp];
  167. }
  168. }
  169.  
  170. void unpack(z_stream zstream, unsigned char * dst, unsigned int dst_size, unsigned char * src, unsigned int src_size, unsigned int h, unsigned int rowbytes, unsigned char bpp)
  171. {
  172. unsigned int j;
  173. unsigned char * row = dst;
  174. unsigned char * prev_row = NULL;
  175.  
  176. zstream.next_out = dst;
  177. zstream.avail_out = dst_size;
  178. zstream.next_in = src;
  179. zstream.avail_in = src_size;
  180. inflate(&zstream, Z_FINISH);
  181. inflateReset(&zstream);
  182.  
  183. for (j=0; j<h; j++)
  184. {
  185. switch (*row++)
  186. {
  187. case 0: break;
  188. case 1: read_sub_row(row, rowbytes, bpp); break;
  189. case 2: read_up_row(row, prev_row, rowbytes, bpp); break;
  190. case 3: read_average_row(row, prev_row, rowbytes, bpp); break;
  191. case 4: read_paeth_row(row, prev_row, rowbytes, bpp); break;
  192. }
  193. prev_row = row;
  194. row += rowbytes;
  195. }
  196. }
  197.  
  198. void compose0(unsigned char * dst1, unsigned int dstbytes1, unsigned char * dst2, unsigned int dstbytes2, unsigned char * src, unsigned int srcbytes, unsigned int w, unsigned int h, unsigned int bop, unsigned char depth)
  199. {
  200. unsigned int i, j, g, a;
  201. unsigned char * sp;
  202. unsigned char * dp1;
  203. unsigned int * dp2;
  204.  
  205. for (j=0; j<h; j++)
  206. {
  207. sp = src+1;
  208. dp1 = dst1;
  209. dp2 = (unsigned int*)dst2;
  210.  
  211. if (bop == PNG_BLEND_OP_SOURCE)
  212. {
  213. switch (depth)
  214. {
  215. case 16: for (i=0; i<w; i++) { a = 0xFF; if (trnssize && readshort(sp)==trns1) a = 0; *dp1++ = *sp; *dp2++ = (a << 24) + (*sp << 16) + (*sp << 8) + *sp; sp+=2; } break;
  216. case 8: for (i=0; i<w; i++) { a = 0xFF; if (trnssize && *sp==trns1) a = 0; *dp1++ = *sp; *dp2++ = (a << 24) + (*sp << 16) + (*sp << 8) + *sp; sp++; } break;
  217. case 4: for (i=0; i<w; i++) { g = (sp[i>>1] & mask4[i&1]) >> shift4[i&1]; a = 0xFF; if (trnssize && g==trns1) a = 0; *dp1++ = g*0x11; *dp2++ = (a<<24) + g*0x111111; } break;
  218. case 2: for (i=0; i<w; i++) { g = (sp[i>>2] & mask2[i&3]) >> shift2[i&3]; a = 0xFF; if (trnssize && g==trns1) a = 0; *dp1++ = g*0x55; *dp2++ = (a<<24) + g*0x555555; } break;
  219. case 1: for (i=0; i<w; i++) { g = (sp[i>>3] & mask1[i&7]) >> shift1[i&7]; a = 0xFF; if (trnssize && g==trns1) a = 0; *dp1++ = g*0xFF; *dp2++ = (a<<24) + g*0xFFFFFF; } break;
  220. }
  221. }
  222. else /* PNG_BLEND_OP_OVER */
  223. {
  224. switch (depth)
  225. {
  226. case 16: for (i=0; i<w; i++, dp1++, dp2++) { if (readshort(sp) != trns1) { *dp1 = *sp; *dp2 = 0xFF000000 + (*sp << 16) + (*sp << 8) + *sp; } sp+=2; } break;
  227. case 8: for (i=0; i<w; i++, dp1++, dp2++) { if (*sp != trns1) { *dp1 = *sp; *dp2 = 0xFF000000 + (*sp << 16) + (*sp << 8) + *sp; } sp++; } break;
  228. case 4: for (i=0; i<w; i++, dp1++, dp2++) { g = (sp[i>>1] & mask4[i&1]) >> shift4[i&1]; if (g != trns1) { *dp1 = g*0x11; *dp2 = 0xFF000000+g*0x111111; } } break;
  229. case 2: for (i=0; i<w; i++, dp1++, dp2++) { g = (sp[i>>2] & mask2[i&3]) >> shift2[i&3]; if (g != trns1) { *dp1 = g*0x55; *dp2 = 0xFF000000+g*0x555555; } } break;
  230. case 1: for (i=0; i<w; i++, dp1++, dp2++) { g = (sp[i>>3] & mask1[i&7]) >> shift1[i&7]; if (g != trns1) { *dp1 = g*0xFF; *dp2 = 0xFF000000+g*0xFFFFFF; } } break;
  231. }
  232. }
  233.  
  234. src += srcbytes;
  235. dst1 += dstbytes1;
  236. dst2 += dstbytes2;
  237. }
  238. }
  239.  
  240. void compose2(unsigned char * dst1, unsigned int dstbytes1, unsigned char * dst2, unsigned int dstbytes2, unsigned char * src, unsigned int srcbytes, unsigned int w, unsigned int h, unsigned int bop, unsigned char depth)
  241. {
  242. unsigned int i, j;
  243. unsigned int r, g, b, a;
  244. unsigned char * sp;
  245. unsigned char * dp1;
  246. unsigned int * dp2;
  247.  
  248. for (j=0; j<h; j++)
  249. {
  250. sp = src+1;
  251. dp1 = dst1;
  252. dp2 = (unsigned int*)dst2;
  253.  
  254. if (bop == PNG_BLEND_OP_SOURCE)
  255. {
  256. if (depth == 8)
  257. {
  258. for (i=0; i<w; i++)
  259. {
  260. r = *sp++;
  261. g = *sp++;
  262. b = *sp++;
  263. a = 0xFF;
  264. if (trnssize && r==trns1 && g==trns2 && b==trns3)
  265. a = 0;
  266. *dp1++ = r; *dp1++ = g; *dp1++ = b;
  267. *dp2++ = (a << 24) + (b << 16) + (g << 8) + r;
  268. }
  269. }
  270. else
  271. {
  272. for (i=0; i<w; i++, sp+=6)
  273. {
  274. r = *sp;
  275. g = *(sp+2);
  276. b = *(sp+4);
  277. a = 0xFF;
  278. if (trnssize && readshort(sp)==trns1 && readshort(sp+2)==trns2 && readshort(sp+4)==trns3)
  279. a = 0;
  280. *dp1++ = r; *dp1++ = g; *dp1++ = b;
  281. *dp2++ = (a << 24) + (b << 16) + (g << 8) + r;
  282. }
  283. }
  284. }
  285. else /* PNG_BLEND_OP_OVER */
  286. {
  287. if (depth == 8)
  288. {
  289. for (i=0; i<w; i++, sp+=3, dp1+=3, dp2++)
  290. if ((*sp != trns1) || (*(sp+1) != trns2) || (*(sp+2) != trns3))
  291. {
  292. *dp1 = *sp; *(dp1+1) = *(sp+1); *(dp1+2) = *(sp+2);
  293. *dp2 = 0xFF000000 + (*(sp+2) << 16) + (*(sp+1) << 8) + *sp;
  294. }
  295. }
  296. else
  297. {
  298. for (i=0; i<w; i++, sp+=6, dp1+=3, dp2++)
  299. if ((readshort(sp) != trns1) || (readshort(sp+2) != trns2) || (readshort(sp+4) != trns3))
  300. {
  301. *dp1 = *sp; *(dp1+1) = *(sp+2); *(dp1+2) = *(sp+4);
  302. *dp2 = 0xFF000000 + (*(sp+4) << 16) + (*(sp+2) << 8) + *sp;
  303. }
  304. }
  305. }
  306. src += srcbytes;
  307. dst1 += dstbytes1;
  308. dst2 += dstbytes2;
  309. }
  310. }
  311.  
  312. void compose3(unsigned char * dst1, unsigned int dstbytes1, unsigned char * dst2, unsigned int dstbytes2, unsigned char * src, unsigned int srcbytes, unsigned int w, unsigned int h, unsigned int bop, unsigned char depth)
  313. {
  314. unsigned int i, j;
  315. unsigned int r, g, b, a;
  316. unsigned int r2, g2, b2, a2;
  317. int u, v, al;
  318. unsigned char col;
  319. unsigned char * sp;
  320. unsigned char * dp1;
  321. unsigned int * dp2;
  322.  
  323. for (j=0; j<h; j++)
  324. {
  325. sp = src+1;
  326. dp1 = dst1;
  327. dp2 = (unsigned int*)dst2;
  328.  
  329. for (i=0; i<w; i++)
  330. {
  331. switch (depth)
  332. {
  333. case 1: col = (sp[i>>3] & mask1[i&7]) >> shift1[i&7]; break;
  334. case 2: col = (sp[i>>2] & mask2[i&3]) >> shift2[i&3]; break;
  335. case 4: col = (sp[i>>1] & mask4[i&1]) >> shift4[i&1]; break;
  336. default: col = sp[i];
  337. }
  338.  
  339. r = pal[col][0];
  340. g = pal[col][1];
  341. b = pal[col][2];
  342. a = trns[col];
  343.  
  344. if (bop == PNG_BLEND_OP_SOURCE)
  345. {
  346. *dp1++ = col;
  347. *dp2++ = (a << 24) + (b << 16) + (g << 8) + r;
  348. }
  349. else /* PNG_BLEND_OP_OVER */
  350. {
  351. if (a == 255)
  352. {
  353. *dp1++ = col;
  354. *dp2++ = (a << 24) + (b << 16) + (g << 8) + r;
  355. }
  356. else
  357. if (a != 0)
  358. {
  359. if ((a2 = (*dp2)>>24) != 0)
  360. {
  361. keep_original = 0;
  362. u = a*255;
  363. v = (255-a)*a2;
  364. al = 255*255-(255-a)*(255-a2);
  365. r2 = ((*dp2)&255);
  366. g2 = (((*dp2)>>8)&255);
  367. b2 = (((*dp2)>>16)&255);
  368. r = (r*u + r2*v)/al;
  369. g = (g*u + g2*v)/al;
  370. b = (b*u + b2*v)/al;
  371. a = al/255;
  372. }
  373. *dp1++ = col;
  374. *dp2++ = (a << 24) + (b << 16) + (g << 8) + r;
  375. }
  376. else
  377. {
  378. dp1++;
  379. dp2++;
  380. }
  381. }
  382. }
  383. src += srcbytes;
  384. dst1 += dstbytes1;
  385. dst2 += dstbytes2;
  386. }
  387. }
  388.  
  389. void compose4(unsigned char * dst, unsigned int dstbytes, unsigned char * src, unsigned int srcbytes, unsigned int w, unsigned int h, unsigned int bop, unsigned char depth)
  390. {
  391. unsigned int i, j, step;
  392. unsigned int g, a, g2, a2;
  393. int u, v, al;
  394. unsigned char * sp;
  395. unsigned char * dp;
  396.  
  397. step = (depth+7)/8;
  398.  
  399. for (j=0; j<h; j++)
  400. {
  401. sp = src+1;
  402. dp = dst;
  403.  
  404. if (bop == PNG_BLEND_OP_SOURCE)
  405. {
  406. for (i=0; i<w; i++)
  407. {
  408. g = *sp; sp += step;
  409. a = *sp; sp += step;
  410. *dp++ = g;
  411. *dp++ = a;
  412. }
  413. }
  414. else /* PNG_BLEND_OP_OVER */
  415. {
  416. for (i=0; i<w; i++)
  417. {
  418. g = *sp; sp += step;
  419. a = *sp; sp += step;
  420. if (a == 255)
  421. {
  422. *dp++ = g;
  423. *dp++ = a;
  424. }
  425. else
  426. if (a != 0)
  427. {
  428. if ((a2 = *(dp+1)) != 0)
  429. {
  430. u = a*255;
  431. v = (255-a)*a2;
  432. al = 255*255-(255-a)*(255-a2);
  433. g2 = ((*dp)&255);
  434. g = (g*u + g2*v)/al;
  435. a = al/255;
  436. }
  437. *dp++ = g;
  438. *dp++ = a;
  439. }
  440. else
  441. dp+=2;
  442. }
  443. }
  444. src += srcbytes;
  445. dst += dstbytes;
  446. }
  447. }
  448.  
  449. void compose6(unsigned char * dst, unsigned int dstbytes, unsigned char * src, unsigned int srcbytes, unsigned int w, unsigned int h, unsigned int bop, unsigned char depth)
  450. {
  451. printf("compose6\n");
  452. unsigned int i, j, step;
  453. unsigned int r, g, b, a;
  454. unsigned int r2, g2, b2, a2;
  455. int u, v, al;
  456. unsigned char * sp;
  457. unsigned int * dp;
  458.  
  459. step = (depth+7)/8;
  460.  
  461. for (j=0; j<h; j++)
  462. {
  463. sp = src+1;
  464. dp = (unsigned int*)dst;
  465.  
  466. if (bop == PNG_BLEND_OP_SOURCE)
  467. {
  468. for (i=0; i<w; i++)
  469. {
  470. printf("i:%i\n",i);
  471. r = *sp; sp += step;
  472. g = *sp; sp += step;
  473. b = *sp; sp += step;
  474. a = *sp; sp += step;
  475. *dp++ = (a << 24) + (b << 16) + (g << 8) + r;
  476. }
  477. printf("exit for\n");
  478. }
  479. else /* PNG_BLEND_OP_OVER */
  480. {
  481. for (i=0; i<w; i++)
  482. {
  483. r = *sp; sp += step;
  484. g = *sp; sp += step;
  485. b = *sp; sp += step;
  486. a = *sp; sp += step;
  487. if (a == 255)
  488. *dp++ = (a << 24) + (b << 16) + (g << 8) + r;
  489. else
  490. if (a != 0)
  491. {
  492. if ((a2 = (*dp)>>24) != 0)
  493. {
  494. u = a*255;
  495. v = (255-a)*a2;
  496. al = 255*255-(255-a)*(255-a2);
  497. r2 = ((*dp)&255);
  498. g2 = (((*dp)>>8)&255);
  499. b2 = (((*dp)>>16)&255);
  500. r = (r*u + r2*v)/al;
  501. g = (g*u + g2*v)/al;
  502. b = (b*u + b2*v)/al;
  503. a = al/255;
  504. }
  505. *dp++ = (a << 24) + (b << 16) + (g << 8) + r;
  506. }
  507. else
  508. dp++;
  509. }
  510. }
  511. src += srcbytes;
  512. dst += dstbytes;
  513. }
  514. }
  515.  
  516. int LoadAPNG(char * szIn, unsigned int *pWidth, unsigned int *pHeight, unsigned int *pChannels, unsigned char *pColType, unsigned int *pFirst, unsigned int *pLast, unsigned char **ppOut1, unsigned char **ppOut2, unsigned short **ppDelays)
  517. {
  518. unsigned char sig[8];
  519. unsigned int i, j;
  520. unsigned int len, chunk, seq, crc;
  521. unsigned int w, h, w0, h0, x0, y0;
  522. unsigned char depth, coltype, compr, filter, interl;
  523. unsigned char pixeldepth, bpp;
  524. unsigned int rowbytes, frames, loops, first_visible, cur_frame, channels;
  525. unsigned int outrow1, outrow2, outimg1, outimg2;
  526. unsigned short d1, d2;
  527. unsigned char c, dop, bop;
  528. int imagesize, zbuf_size, zsize;
  529. z_stream zstream;
  530. unsigned char * pOut1;
  531. unsigned char * pOut2;
  532. unsigned char * pTemp;
  533. unsigned char * pData;
  534. unsigned char * pImg1;
  535. unsigned char * pImg2;
  536. unsigned char * pDst1;
  537. unsigned char * pDst2;
  538. unsigned short * pDelays;
  539. FILE * f1;
  540. int res = 1;
  541.  
  542. if ((f1 = fopen(szIn, "rb")) == 0)
  543. {
  544. printf("Error: can't open '%s'\n", szIn);
  545. return res;
  546. }
  547.  
  548. printf("Reading '%s'...\n", szIn);
  549.  
  550. frames = 0;
  551. loops = 0;
  552. first_visible = 0;
  553. cur_frame = 0;
  554. zsize = 0;
  555. x0 = 0;
  556. y0 = 0;
  557. bop = PNG_BLEND_OP_SOURCE;
  558. palsize = 0;
  559. trnssize = 0;
  560. trns_idx = -1;
  561.  
  562. memset(trns, 255, 256);
  563.  
  564. zstream.zalloc = Z_NULL;
  565. zstream.zfree = Z_NULL;
  566. zstream.opaque = Z_NULL;
  567. inflateInit(&zstream);
  568.  
  569. do
  570. {
  571. if (fread(sig, 1, 8, f1) != 8)
  572. {
  573. printf("Error: can't read the sig\n");
  574. break;
  575. }
  576. if (memcmp(sig, png_sign, 8) != 0)
  577. {
  578. printf("Error: wrong PNG sig\n");
  579. break;
  580. }
  581.  
  582. if (read32(&len, f1)) break;
  583. if (read32(&chunk, f1)) break;
  584.  
  585. if (len != 13 || chunk != 0x49484452) /* IHDR */
  586. {
  587. printf("Error: missing IHDR\n");
  588. break;
  589. }
  590.  
  591. if (read32(&w, f1)) break;
  592. if (read32(&h, f1)) break;
  593. w0 = w;
  594. h0 = h;
  595. if (fread(&depth, 1, 1, f1) != 1) break;
  596. if (fread(&coltype, 1, 1, f1) != 1) break;
  597. if (fread(&compr, 1, 1, f1) != 1) break;
  598. if (fread(&filter, 1, 1, f1) != 1) break;
  599. if (fread(&interl, 1, 1, f1) != 1) break;
  600. if (read32(&crc, f1)) break;
  601.  
  602. channels = 1;
  603. if (coltype == 2)
  604. channels = 3;
  605. else
  606. if (coltype == 4)
  607. channels = 2;
  608. else
  609. if (coltype == 6)
  610. channels = 4;
  611.  
  612. pixeldepth = depth*channels;
  613. bpp = (pixeldepth + 7) >> 3;
  614. rowbytes = ROWBYTES(pixeldepth, w);
  615.  
  616. imagesize = (rowbytes + 1) * h;
  617. zbuf_size = imagesize + ((imagesize + 7) >> 3) + ((imagesize + 63) >> 6) + 11;
  618.  
  619. /*
  620. * We'll render into 2 output buffers, first in original coltype,
  621. * second in RGBA.
  622. *
  623. * It's better to try to keep the original coltype, but if dispose/blend
  624. * operations will make it impossible, then we'll save RGBA version instead.
  625. */
  626.  
  627. outrow1 = w*channels; /* output coltype = input coltype */
  628. outrow2 = w*4; /* output coltype = RGBA */
  629. outimg1 = h*outrow1;
  630. outimg2 = h*outrow2;
  631.  
  632. pOut1 = (unsigned char *)malloc((frames+1)*outimg1);
  633. pOut2 = (unsigned char *)malloc((frames+1)*outimg2);
  634. pDelays = (unsigned short *)malloc((frames+1)*4);
  635. pTemp = (unsigned char *)malloc(imagesize);
  636. pData = (unsigned char *)malloc(zbuf_size);
  637. if (!pOut1 || !pOut2 || !pDelays || !pTemp || !pData)
  638. {
  639. printf("Error: not enough memory\n");
  640. break;
  641. }
  642.  
  643. pImg1 = pOut1;
  644. pImg2 = pOut2;
  645. memset(pOut1, 0, outimg1);
  646. memset(pOut2, 0, outimg2);
  647. pDelays[0] = 0;
  648. pDelays[1] = 0;
  649.  
  650. while ( !feof(f1) )
  651. {
  652. if (read32(&len, f1)) break;
  653. if (read32(&chunk, f1)) break;
  654.  
  655. if (chunk == 0x504C5445) /* PLTE */
  656. {
  657. unsigned int col;
  658. for (i=0; i<len; i++)
  659. {
  660. if (fread(&c, 1, 1, f1) != 1) break;
  661. col = i/3;
  662. if (col<256)
  663. {
  664. pal[col][i%3] = c;
  665. palsize = col+1;
  666. }
  667. }
  668. if (read32(&crc, f1)) break;
  669. }
  670. else
  671. if (chunk == 0x74524E53) /* tRNS */
  672. {
  673. for (i=0; i<len; i++)
  674. {
  675. if (fread(&c, 1, 1, f1) != 1) break;
  676. if (i<256)
  677. {
  678. trns[i] = c;
  679. trnssize = i+1;
  680. if (c == 0 && coltype == 3 && trns_idx == -1)
  681. trns_idx = i;
  682. }
  683. }
  684. if (coltype == 0)
  685. {
  686. if (trnssize == 2)
  687. {
  688. trns1 = readshort(&trns[0]);
  689. switch (depth)
  690. {
  691. case 16: trns[1] = trns[0]; trns[0] = 0; break;
  692. case 4: trns[1] *= 0x11; break;
  693. case 2: trns[1] *= 0x55; break;
  694. case 1: trns[1] *= 0xFF; break;
  695. }
  696. trns_idx = trns[1];
  697. }
  698. else
  699. trnssize = 0;
  700. }
  701. else
  702. if (coltype == 2)
  703. {
  704. if (trnssize == 6)
  705. {
  706. trns1 = readshort(&trns[0]);
  707. trns2 = readshort(&trns[2]);
  708. trns3 = readshort(&trns[4]);
  709. if (depth == 16)
  710. {
  711. trns[1] = trns[0]; trns[0] = 0;
  712. trns[3] = trns[2]; trns[2] = 0;
  713. trns[5] = trns[4]; trns[4] = 0;
  714. }
  715. }
  716. else
  717. trnssize = 0;
  718. }
  719. if (read32(&crc, f1)) break;
  720. }
  721. else
  722. if (chunk == 0x6163544C) /* acTL */
  723. {
  724. if (read32(&frames, f1)) break;
  725. if (read32(&loops, f1)) break;
  726. if (read32(&crc, f1)) break;
  727. free(pOut1);
  728. free(pOut2);
  729. free(pDelays);
  730. pOut1 = (unsigned char *)malloc((frames+1)*outimg1);
  731. pOut2 = (unsigned char *)malloc((frames+1)*outimg2);
  732. pDelays = (unsigned short *)malloc((frames+1)*4);
  733. pImg1 = pOut1;
  734. pImg2 = pOut2;
  735. memset(pOut1, 0, outimg1);
  736. memset(pOut2, 0, outimg2);
  737. }
  738. else
  739. if (chunk == 0x6663544C) /* fcTL */
  740. {
  741. if (zsize == 0)
  742. first_visible = 1;
  743. else
  744. {
  745. if (dop == PNG_DISPOSE_OP_PREVIOUS)
  746. {
  747. if (coltype != 6)
  748. memcpy(pImg1 + outimg1, pImg1, outimg1);
  749. if (coltype != 4)
  750. memcpy(pImg2 + outimg2, pImg2, outimg2);
  751. }
  752.  
  753. pDst1 = pImg1 + y0*outrow1 + x0*channels;
  754. pDst2 = pImg2 + y0*outrow2 + x0*4;
  755. unpack(zstream, pTemp, imagesize, pData, zsize, h0, rowbytes, bpp);
  756. switch (coltype)
  757. {
  758. case 0: compose0(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  759. case 2: compose2(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  760. case 3: compose3(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  761. case 4: compose4(pDst1, outrow1, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  762. case 6: compose6( pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  763. }
  764. zsize = 0;
  765.  
  766. if (dop != PNG_DISPOSE_OP_PREVIOUS)
  767. {
  768. if (coltype != 6)
  769. memcpy(pImg1 + outimg1, pImg1, outimg1);
  770. if (coltype != 4)
  771. memcpy(pImg2 + outimg2, pImg2, outimg2);
  772.  
  773. if (dop == PNG_DISPOSE_OP_BACKGROUND)
  774. {
  775. pDst1 += outimg1;
  776. pDst2 += outimg2;
  777.  
  778. for (j=0; j<h0; j++)
  779. {
  780. switch (coltype)
  781. {
  782. case 0: memset(pDst2, 0, w0*4); if (trnssize) memset(pDst1, trns_idx, w0); else keep_original = 0; break;
  783. case 2: memset(pDst2, 0, w0*4); if (trnssize) for (i=0; i<w0; i++) { pDst1[i*3] = trns[1]; pDst1[i*3+1] = trns[3]; pDst1[i*3+2] = trns[5]; } else keep_original = 0; break;
  784. case 3: memset(pDst2, 0, w0*4); if (trns_idx >= 0) memset(pDst1, trns_idx, w0); else keep_original = 0; break;
  785. case 4: memset(pDst1, 0, w0*2); break;
  786. case 6: memset(pDst2, 0, w0*4); break;
  787. }
  788. pDst1 += outrow1;
  789. pDst2 += outrow2;
  790. }
  791. }
  792. }
  793. }
  794.  
  795. pImg1 += outimg1;
  796. pImg2 += outimg2;
  797.  
  798. if (read32(&seq, f1)) break;
  799. if (read32(&w0, f1)) break;
  800. if (read32(&h0, f1)) break;
  801. if (read32(&x0, f1)) break;
  802. if (read32(&y0, f1)) break;
  803. if (read16(&d1, f1)) break;
  804. if (read16(&d2, f1)) break;
  805. if (fread(&dop, 1, 1, f1) != 1) break;
  806. if (fread(&bop, 1, 1, f1) != 1) break;
  807. if (read32(&crc, f1)) break;
  808.  
  809. if (cur_frame == 0)
  810. {
  811. bop = PNG_BLEND_OP_SOURCE;
  812. if (dop == PNG_DISPOSE_OP_PREVIOUS)
  813. dop = PNG_DISPOSE_OP_BACKGROUND;
  814. }
  815.  
  816. if (coltype<=3 && trnssize==0)
  817. bop = PNG_BLEND_OP_SOURCE;
  818.  
  819. rowbytes = ROWBYTES(pixeldepth, w0);
  820.  
  821. cur_frame++;
  822. pDelays[cur_frame*2] = d1;
  823. pDelays[cur_frame*2+1] = d2;
  824. }
  825. else
  826. if (chunk == 0x49444154) /* IDAT */
  827. {
  828. if (fread(pData + zsize, 1, len, f1) != len) break;
  829. zsize += len;
  830. if (read32(&crc, f1)) break;
  831. }
  832. else
  833. if (chunk == 0x66644154) /* fdAT */
  834. {
  835. if (read32(&seq, f1)) break;
  836. len -= 4;
  837. if (fread(pData + zsize, 1, len, f1) != len) break;
  838. zsize += len;
  839. if (read32(&crc, f1)) break;
  840. }
  841. else
  842. if (chunk == 0x49454E44) /* IEND */
  843. {
  844. pDst1 = pImg1 + y0*outrow1 + x0*channels;
  845. pDst2 = pImg2 + y0*outrow2 + x0*4;
  846. unpack(zstream, pTemp, imagesize, pData, zsize, h0, rowbytes, bpp);
  847. switch (coltype)
  848. {
  849. case 0: compose0(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  850. case 2: compose2(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  851. case 3: compose3(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  852. case 4: compose4(pDst1, outrow1, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  853. case 6: compose6( pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
  854. }
  855.  
  856. if (cur_frame == frames)
  857. res = 0;
  858.  
  859. break;
  860. }
  861. else
  862. {
  863. c = (unsigned char)(chunk>>24);
  864. if (notabc(c)) break;
  865. c = (unsigned char)((chunk>>16) & 0xFF);
  866. if (notabc(c)) break;
  867. c = (unsigned char)((chunk>>8) & 0xFF);
  868. if (notabc(c)) break;
  869. c = (unsigned char)(chunk & 0xFF);
  870. if (notabc(c)) break;
  871.  
  872. fseek(f1, len, SEEK_CUR);
  873. if (read32(&crc, f1)) break;
  874. }
  875. }
  876.  
  877. *pWidth = w;
  878. *pHeight = h;
  879. *pChannels = channels;
  880. *pColType = coltype;
  881. *pFirst = first_visible;
  882. *pLast = cur_frame;
  883. *ppOut1 = pOut1;
  884. *ppOut2 = pOut2;
  885. *ppDelays = pDelays;
  886.  
  887. free(pData);
  888. free(pTemp);
  889.  
  890. } while (0);
  891.  
  892. inflateEnd(&zstream);
  893. fclose(f1);
  894. return res;
  895. }
  896.  
  897. void write_chunk(FILE * f, const char * name, unsigned char * data, unsigned int length)
  898. {
  899. unsigned int crc = crc32(0, Z_NULL, 0);
  900. unsigned int len = swap32(length);
  901.  
  902. fwrite(&len, 1, 4, f);
  903. fwrite(name, 1, 4, f);
  904. crc = crc32(crc, (const Bytef *)name, 4);
  905.  
  906. if (data != NULL && length > 0)
  907. {
  908. fwrite(data, 1, length, f);
  909. crc = crc32(crc, data, length);
  910. }
  911.  
  912. crc = swap32(crc);
  913. fwrite(&crc, 1, 4, f);
  914. }
  915.  
  916. void write_IDATs(FILE * f, unsigned char * data, unsigned int length, unsigned int idat_size)
  917. {
  918. unsigned int z_cmf = data[0];
  919. if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
  920. {
  921. if (length >= 2)
  922. {
  923. unsigned int z_cinfo = z_cmf >> 4;
  924. unsigned int half_z_window_size = 1 << (z_cinfo + 7);
  925. while (idat_size <= half_z_window_size && half_z_window_size >= 256)
  926. {
  927. z_cinfo--;
  928. half_z_window_size >>= 1;
  929. }
  930. z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
  931. if (data[0] != (unsigned char)z_cmf)
  932. {
  933. data[0] = (unsigned char)z_cmf;
  934. data[1] &= 0xe0;
  935. data[1] += (unsigned char)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
  936. }
  937. }
  938. }
  939.  
  940. while (length > 0)
  941. {
  942. unsigned int ds = length;
  943. if (ds > PNG_ZBUF_SIZE)
  944. ds = PNG_ZBUF_SIZE;
  945.  
  946. write_chunk(f, "IDAT", data, ds);
  947.  
  948. data += ds;
  949. length -= ds;
  950. }
  951. }
  952.  
  953. void SavePNG(char * szPath, unsigned char * pdata, unsigned short * delays, unsigned int w, unsigned int h, unsigned int first, unsigned int last, unsigned int bpp, unsigned char coltype)
  954. {
  955. struct IHDR
  956. {
  957. unsigned int mWidth;
  958. unsigned int mHeight;
  959. unsigned char mDepth;
  960. unsigned char mColorType;
  961. unsigned char mCompression;
  962. unsigned char mFilterMethod;
  963. unsigned char mInterlaceMethod;
  964. } ihdr = { swap32(w), swap32(h), 8, coltype, 0, 0, 0 };
  965.  
  966. char szOut[256];
  967.  
  968. z_stream zstream1;
  969. z_stream zstream2;
  970. FILE * f;
  971. unsigned int i, j, n, len;
  972.  
  973. unsigned int rowbytes = w * bpp;
  974. unsigned int idat_size = (rowbytes + 1) * h;
  975. unsigned int zbuf_size = idat_size + ((idat_size + 7) >> 3) + ((idat_size + 63) >> 6) + 11;
  976.  
  977. unsigned char * row_buf = (unsigned char *)malloc(rowbytes + 1);
  978. unsigned char * sub_row = (unsigned char *)malloc(rowbytes + 1);
  979. unsigned char * up_row = (unsigned char *)malloc(rowbytes + 1);
  980. unsigned char * avg_row = (unsigned char *)malloc(rowbytes + 1);
  981. unsigned char * paeth_row = (unsigned char *)malloc(rowbytes + 1);
  982. unsigned char * zbuf1 = (unsigned char *)malloc(zbuf_size);
  983. unsigned char * zbuf2 = (unsigned char *)malloc(zbuf_size);
  984.  
  985. if (!row_buf || !sub_row || !up_row || !avg_row || !paeth_row || !zbuf1 || !zbuf2)
  986. return;
  987.  
  988. row_buf[0] = 0;
  989. sub_row[0] = 1;
  990. up_row[0] = 2;
  991. avg_row[0] = 3;
  992. paeth_row[0] = 4;
  993.  
  994. int ret;
  995. zstream1.data_type = Z_BINARY;
  996. zstream1.zalloc = Z_NULL;
  997. zstream1.zfree = Z_NULL;
  998. zstream1.opaque = Z_NULL;
  999. ret = deflateInit2(&zstream1, Z_BEST_COMPRESSION, 8, 15, 8, Z_DEFAULT_STRATEGY);
  1000. printf("1 ret defalteInit2:%i\n",ret);
  1001.  
  1002. zstream2.data_type = Z_BINARY;
  1003. zstream2.zalloc = Z_NULL;
  1004. zstream2.zfree = Z_NULL;
  1005. zstream2.opaque = Z_NULL;
  1006. ret = deflateInit2(&zstream2, Z_BEST_COMPRESSION, 8, 15, 8, Z_FILTERED);
  1007. printf("2 ret defalteInit2:%i\n",ret);
  1008.  
  1009. len = sprintf(szOut, "%d", last);
  1010.  
  1011. for (n=first; n<=last; n++)
  1012. {
  1013. printf("extracting frame %d of %d\n", n, last);
  1014.  
  1015. if (n > 0)
  1016. {
  1017. sprintf(szOut, "%s%.*d.txt", szPath, len, n);
  1018. if ((f = fopen(szOut, "wt")) != 0)
  1019. {
  1020. fprintf(f, "delay=%d/%d\n", delays[n*2], delays[n*2+1]);
  1021. fclose(f);
  1022. }
  1023. }
  1024.  
  1025. sprintf(szOut, "%s%.*d.png", szPath, len, n);
  1026. if ((f = fopen(szOut, "wb")) != 0)
  1027. {
  1028. int a, b, c, pa, pb, pc, p, v;
  1029. unsigned char * prev;
  1030. unsigned char * row;
  1031.  
  1032. fwrite(png_sign, 1, 8, f);
  1033. write_chunk(f, "IHDR", (unsigned char *)(&ihdr), 13);
  1034.  
  1035. if (palsize > 0)
  1036. write_chunk(f, "PLTE", (unsigned char *)(&pal), palsize*3);
  1037.  
  1038. if (trnssize > 0)
  1039. write_chunk(f, "tRNS", trns, trnssize);
  1040.  
  1041. zstream1.next_out = zbuf1;
  1042. zstream1.avail_out = zbuf_size;
  1043. zstream2.next_out = zbuf2;
  1044. zstream2.avail_out = zbuf_size;
  1045.  
  1046. prev = NULL;
  1047. row = pdata + n*h*rowbytes;
  1048.  
  1049. for (j=0; j<h; j++)
  1050. {
  1051. unsigned char * out;
  1052. unsigned int sum = 0;
  1053. unsigned char * best_row = row_buf;
  1054. unsigned int mins = ((unsigned int)(-1)) >> 1;
  1055.  
  1056. out = row_buf+1;
  1057. for (i=0; i<rowbytes; i++)
  1058. {
  1059. v = out[i] = row[i];
  1060. sum += (v < 128) ? v : 256 - v;
  1061. }
  1062. mins = sum;
  1063.  
  1064. sum = 0;
  1065. out = sub_row+1;
  1066. for (i=0; i<bpp; i++)
  1067. {
  1068. v = out[i] = row[i];
  1069. sum += (v < 128) ? v : 256 - v;
  1070. }
  1071. for (i=bpp; i<rowbytes; i++)
  1072. {
  1073. v = out[i] = row[i] - row[i-bpp];
  1074. sum += (v < 128) ? v : 256 - v;
  1075. if (sum > mins) break;
  1076. }
  1077. if (sum < mins)
  1078. {
  1079. mins = sum;
  1080. best_row = sub_row;
  1081. }
  1082.  
  1083. if (prev)
  1084. {
  1085. sum = 0;
  1086. out = up_row+1;
  1087. for (i=0; i<rowbytes; i++)
  1088. {
  1089. v = out[i] = row[i] - prev[i];
  1090. sum += (v < 128) ? v : 256 - v;
  1091. if (sum > mins) break;
  1092. }
  1093. if (sum < mins)
  1094. {
  1095. mins = sum;
  1096. best_row = up_row;
  1097. }
  1098.  
  1099. sum = 0;
  1100. out = avg_row+1;
  1101. for (i=0; i<bpp; i++)
  1102. {
  1103. v = out[i] = row[i] - prev[i]/2;
  1104. sum += (v < 128) ? v : 256 - v;
  1105. }
  1106. for (i=bpp; i<rowbytes; i++)
  1107. {
  1108. v = out[i] = row[i] - (prev[i] + row[i-bpp])/2;
  1109. sum += (v < 128) ? v : 256 - v;
  1110. if (sum > mins) break;
  1111. }
  1112. if (sum < mins)
  1113. {
  1114. mins = sum;
  1115. best_row = avg_row;
  1116. }
  1117.  
  1118. sum = 0;
  1119. out = paeth_row+1;
  1120. for (i=0; i<bpp; i++)
  1121. {
  1122. v = out[i] = row[i] - prev[i];
  1123. sum += (v < 128) ? v : 256 - v;
  1124. }
  1125. for (i=bpp; i<rowbytes; i++)
  1126. {
  1127. a = row[i-bpp];
  1128. b = prev[i];
  1129. c = prev[i-bpp];
  1130. p = b - c;
  1131. pc = a - c;
  1132. pa = abs(p);
  1133. pb = abs(pc);
  1134. pc = abs(p + pc);
  1135. p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
  1136. v = out[i] = row[i] - p;
  1137. sum += (v < 128) ? v : 256 - v;
  1138. if (sum > mins) break;
  1139. }
  1140. if (sum < mins)
  1141. {
  1142. best_row = paeth_row;
  1143. }
  1144. }
  1145. zstream1.next_in = row_buf;
  1146. zstream1.avail_in = rowbytes + 1;
  1147. deflate(&zstream1, Z_NO_FLUSH);
  1148.  
  1149. zstream2.next_in = best_row;
  1150. zstream2.avail_in = rowbytes + 1;
  1151. deflate(&zstream2, Z_NO_FLUSH);
  1152.  
  1153. prev = row;
  1154. row += rowbytes;
  1155. }
  1156. deflate(&zstream1, Z_FINISH);
  1157. deflate(&zstream2, Z_FINISH);
  1158.  
  1159. if (zstream1.total_out <= zstream2.total_out)
  1160. write_IDATs(f, zbuf1, zstream1.total_out, idat_size);
  1161. else
  1162. write_IDATs(f, zbuf2, zstream2.total_out, idat_size);
  1163.  
  1164. deflateReset(&zstream1);
  1165. zstream1.data_type = Z_BINARY;
  1166. deflateReset(&zstream2);
  1167. zstream2.data_type = Z_BINARY;
  1168.  
  1169. write_chunk(f, "IEND", 0, 0);
  1170. fclose(f);
  1171. }
  1172. else
  1173. printf("Error: can't open the file '%s'\n", szOut);
  1174. }
  1175.  
  1176. deflateEnd(&zstream1);
  1177. deflateEnd(&zstream2);
  1178. free(zbuf1);
  1179. free(zbuf2);
  1180. free(row_buf);
  1181. free(sub_row);
  1182. free(up_row);
  1183. free(avg_row);
  1184. free(paeth_row);
  1185. }
  1186.  
  1187. int main(int argc, char** argv)
  1188. {
  1189. char * szIn;
  1190. char * szImg;
  1191. char szOut[256];
  1192. unsigned int w, h, first, last, channels, i, j;
  1193. unsigned char coltype;
  1194. unsigned char * pOut1 = NULL;
  1195. unsigned char * pOut2 = NULL;
  1196. unsigned short * pDelays = NULL;
  1197.  
  1198. printf("\nAPNG Disassembler 2.5\n\n");
  1199.  
  1200. if (argc > 1)
  1201. szIn = argv[1];
  1202. else
  1203. {
  1204. printf("Usage: apngdis apng.png [name]\n");
  1205. return 1;
  1206. }
  1207.  
  1208. if (LoadAPNG(szIn, &w, &h, &channels, &coltype, &first, &last, &pOut1, &pOut2, &pDelays) != 0)
  1209. {
  1210. printf("Error: can't load '%s'\n", szIn);
  1211. return 1;
  1212. }
  1213.  
  1214. strcpy(szOut, szIn);
  1215. for (i=j=0; szOut[i]!=0; i++)
  1216. {
  1217. if (szOut[i] == '\\' || szOut[i] == '/' || szOut[i] == ':')
  1218. j = i+1;
  1219. }
  1220. szOut[j] = 0;
  1221.  
  1222. if (argc > 2)
  1223. {
  1224. szImg = argv[2];
  1225.  
  1226. for (i=j=0; szImg[i]!=0; i++)
  1227. {
  1228. if (szImg[i] == '\\' || szImg[i] == '/' || szImg[i] == ':')
  1229. j = i+1;
  1230. if (szImg[i] == '.')
  1231. szImg[i] = 0;
  1232. }
  1233. strcat(szOut, szImg+j);
  1234. }
  1235. else
  1236. strcat(szOut, "apngframe");
  1237.  
  1238. if (coltype == 6)
  1239. SavePNG(szOut, pOut2, pDelays, w, h, first, last, 4, 6);
  1240. else
  1241. if (coltype == 4)
  1242. SavePNG(szOut, pOut1, pDelays, w, h, first, last, channels, coltype);
  1243. else
  1244. if (keep_original)
  1245. SavePNG(szOut, pOut1, pDelays, w, h, first, last, channels, coltype);
  1246. else
  1247. SavePNG(szOut, pOut2, pDelays, w, h, first, last, 4, 6);
  1248.  
  1249. free(pOut1);
  1250. free(pOut2);
  1251. free(pDelays);
  1252.  
  1253. printf("all done\n");
  1254.  
  1255. return 0;
  1256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement