Otclient  14/8/2020
apngloader.cpp
Go to the documentation of this file.
1 /*
2  * Based on APNG Disassembler 2.3
3  *
4  * Copyright (c) 2009 Max Stepin
5  * maxst at users.sourceforge.net
6  *
7  * GNU LGPL information
8  * --------------------
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  */
25 
26 #include "apngloader.h"
27 #include <cstdio>
28 #include <cstdlib>
29 #include <cstring>
30 #include <fstream>
31 #include <iostream>
32 #include <memory>
33 #include <sstream>
34 
35 #include <zlib.h>
36 
37 #if defined(_MSC_VER) && _MSC_VER >= 1300
38 #define swap16(data) _byteswap_ushort(data)
39 #define swap32(data) _byteswap_ulong(data)
40 #elif __linux__
41 #include <byteswap.h>
42 #define swap16(data) bswap_16(data)
43 #define swap32(data) bswap_32(data)
44 #else
45 #define swap16(data) (((data >> 8) & 255) | ((data & 255) << 8))
46 #define swap32(data) ((swap16(data) << 16) | swap16(data >> 16))
47 #endif
48 
49 #define PNG_ZBUF_SIZE 32768
50 
51 #define PNG_DISPOSE_OP_NONE 0x00
52 #define PNG_DISPOSE_OP_BACKGROUND 0x01
53 #define PNG_DISPOSE_OP_PREVIOUS 0x02
54 
55 #define PNG_BLEND_OP_SOURCE 0x00
56 #define PNG_BLEND_OP_OVER 0x01
57 
58 #define notabc(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
59 
60 #define ROWBYTES(pixel_bits, width) \
61 ((pixel_bits) >= 8 ? \
62 ((width) * (((unsigned int)(pixel_bits)) >> 3)) : \
63 (( ((width) * ((unsigned int)(pixel_bits))) + 7) >> 3) )
64 
65 unsigned char png_sign[8] = {137, 80, 78, 71, 13, 10, 26, 10};
66 
67 int mask4[2]={240,15};
68 int shift4[2]={4,0};
69 
70 int mask2[4]={192,48,12,3};
71 int shift2[4]={6,4,2,0};
72 
73 int mask1[8]={128,64,32,16,8,4,2,1};
74 int shift1[8]={7,6,5,4,3,2,1,0};
75 
76 unsigned int keep_original = 1;
77 unsigned char pal[256][3];
78 unsigned char trns[256];
79 unsigned int palsize, trnssize;
80 unsigned int hasTRNS;
81 unsigned short trns1, trns2, trns3;
82 
83 unsigned int read32(std::istream& f1)
84 {
85  unsigned char a, b, c, d;
86  f1.read((char*)&a, 1);
87  f1.read((char*)&b, 1);
88  f1.read((char*)&c, 1);
89  f1.read((char*)&d, 1);
90  return ((unsigned int)a<<24)+((unsigned int)b<<16)+((unsigned int)c<<8)+(unsigned int)d;
91 }
92 
93 unsigned short read16(std::istream& f1)
94 {
95  unsigned char a, b;
96  f1.read((char*)&a, 1);
97  f1.read((char*)&b, 1);
98  return ((unsigned short)a<<8)+(unsigned short)b;
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 = nullptr;
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 (hasTRNS && 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 (hasTRNS && *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 (hasTRNS && 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 (hasTRNS && 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 (hasTRNS && 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  b = *sp++;
261  g = *sp++;
262  r = *sp++;
263  a = 0xFF;
264  if (hasTRNS && b==trns1 && g==trns2 && r==trns3)
265  a = 0;
266  *dp1++ = b; *dp1++ = g; *dp1++ = r;
267  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
268  }
269  }
270  else
271  {
272  for (i=0; i<w; i++, sp+=6)
273  {
274  b = *sp;
275  g = *(sp+2);
276  r = *(sp+4);
277  a = 0xFF;
278  if (hasTRNS && readshort(sp)==trns1 && readshort(sp+2)==trns2 && readshort(sp+4)==trns3)
279  a = 0;
280  *dp1++ = b; *dp1++ = g; *dp1++ = r;
281  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
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 = 0;
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 8: col = sp[i]; break;
334  case 4: col = (sp[i>>1] & mask4[i&1]) >> shift4[i&1]; break;
335  case 2: col = (sp[i>>2] & mask2[i&3]) >> shift2[i&3]; break;
336  case 1: col = (sp[i>>3] & mask1[i&7]) >> shift1[i&7]; break;
337  }
338 
339  b = pal[col][0];
340  g = pal[col][1];
341  r = pal[col][2];
342  a = trns[col];
343 
344  if (bop == PNG_BLEND_OP_SOURCE)
345  {
346  *dp1++ = col;
347  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
348  }
349  else /* PNG_BLEND_OP_OVER */
350  {
351  if (a == 255)
352  {
353  *dp1++ = col;
354  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
355  }
356  else
357  if (a != 0)
358  {
359  if ((a2 = (*dp2)>>24))
360  {
361  keep_original = 0;
362  u = a*255;
363  v = (255-a)*a2;
364  al = 255*255-(255-a)*(255-a2);
365  b2 = ((*dp2)&255);
366  g2 = (((*dp2)>>8)&255);
367  r2 = (((*dp2)>>16)&255);
368  b = (b*u + b2*v)/al;
369  g = (g*u + g2*v)/al;
370  r = (r*u + r2*v)/al;
371  a = al/255;
372  }
373  *dp1++ = col;
374  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
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)))
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  unsigned int i, j, step;
452  unsigned int r, g, b, a;
453  unsigned int r2, g2, b2, a2;
454  int u, v, al;
455  unsigned char * sp;
456  unsigned int * dp;
457 
458  step = (depth+7)/8;
459 
460  for (j=0; j<h; j++)
461  {
462  sp = src+1;
463  dp = (unsigned int*)dst;
464 
465  if (bop == PNG_BLEND_OP_SOURCE)
466  {
467  for (i=0; i<w; i++)
468  {
469  b = *sp; sp += step;
470  g = *sp; sp += step;
471  r = *sp; sp += step;
472  a = *sp; sp += step;
473  *dp++ = (a << 24) + (r << 16) + (g << 8) + b;
474  }
475  }
476  else /* PNG_BLEND_OP_OVER */
477  {
478  for (i=0; i<w; i++)
479  {
480  b = *sp; sp += step;
481  g = *sp; sp += step;
482  r = *sp; sp += step;
483  a = *sp; sp += step;
484  if (a == 255)
485  *dp++ = (a << 24) + (r << 16) + (g << 8) + b;
486  else
487  if (a != 0)
488  {
489  if ((a2 = (*dp)>>24))
490  {
491  u = a*255;
492  v = (255-a)*a2;
493  al = 255*255-(255-a)*(255-a2);
494  b2 = ((*dp)&255);
495  g2 = (((*dp)>>8)&255);
496  r2 = (((*dp)>>16)&255);
497  b = (b*u + b2*v)/al;
498  g = (g*u + g2*v)/al;
499  r = (r*u + r2*v)/al;
500  a = al/255;
501  }
502  *dp++ = (a << 24) + (r << 16) + (g << 8) + b;
503  }
504  else
505  dp++;
506  }
507  }
508  src += srcbytes;
509  dst += dstbytes;
510  }
511 }
512 
513 int load_apng(std::stringstream& file, struct apng_data *apng)
514 {
515  unsigned int i, j;
516  unsigned int rowbytes;
517  int imagesize, zbuf_size, zsize, trns_idx;
518  unsigned int len, chunk/*, crc, seq*/;
519  unsigned int w, h, w0, h0, x0, y0;
520  unsigned int frames, loops, first_frame, cur_frame;
521  unsigned int outrow1, outrow2, outimg1, outimg2;
522  unsigned short d1, d2;
523  unsigned char c, dop, bop;
524  unsigned char channels, depth, pixeldepth, bpp;
525  unsigned char coltype, compr, filter, interl;
526  z_stream zstream;
527  memset(apng, 0, sizeof(struct apng_data));
528 
529  for (i=0; i<256; i++)
530  {
531  pal[i][0] = i;
532  pal[i][1] = i;
533  pal[i][2] = i;
534  trns[i] = 255;
535  }
536 
537  zstream.zalloc = Z_NULL;
538  zstream.zfree = Z_NULL;
539  zstream.opaque = Z_NULL;
540  inflateInit(&zstream);
541 
542  frames = 1;
543  first_frame = 0;
544  cur_frame = 0;
545  zsize = 0;
546  hasTRNS = 0;
547  trns_idx = -1;
548  x0 = 0;
549  y0 = 0;
550  loops = 0;
551  bop = PNG_BLEND_OP_SOURCE;
552 
553  unsigned char sig[8];
554  unsigned char * pOut1;
555  unsigned char * pOut2;
556  unsigned char * pTemp;
557  unsigned char * pData;
558  unsigned char * pImg1;
559  unsigned char * pImg2;
560  unsigned char * pDst1;
561  unsigned char * pDst2;
562  unsigned short* frames_delay;
563 
564  file.read((char*)sig, 8);
565  if(!file.eof() && memcmp(sig, png_sign, 8) == 0) {
566  len = read32(file);
567  chunk = read32(file);
568 
569  if ((len == 13) && (chunk == 0x49484452)) /* IHDR */
570  {
571  w = w0 = read32(file);
572  h = h0 = read32(file);
573  file.read((char*)&depth, 1);
574  file.read((char*)&coltype, 1);
575  file.read((char*)&compr, 1);
576  file.read((char*)&filter, 1);
577  file.read((char*)&interl, 1);
578  /*crc = */read32(file);
579 
580  channels = 1;
581  if (coltype == 2)
582  channels = 3;
583  else if (coltype == 4)
584  channels = 2;
585  else if (coltype == 6)
586  channels = 4;
587 
588  pixeldepth = depth*channels;
589  bpp = (pixeldepth + 7) >> 3;
590  rowbytes = ROWBYTES(pixeldepth, w);
591 
592  imagesize = (rowbytes + 1) * h;
593  zbuf_size = imagesize + ((imagesize + 7) >> 3) + ((imagesize + 63) >> 6) + 11;
594 
595  /*
596  * We'll render into 2 output buffers, first in original coltype,
597  * second in RGBA.
598  *
599  * It's better to try to keep the original coltype, but if dispose/blend
600  * operations will make it impossible, then we'll save RGBA version instead.
601  */
602 
603  outrow1 = w*channels; /* output coltype = input coltype */
604  outrow2 = w*4; /* output coltype = RGBA */
605  outimg1 = h*outrow1;
606  outimg2 = h*outrow2;
607 
608  pOut1=(unsigned char *)malloc(outimg1);
609  pOut2=(unsigned char *)malloc(outimg2);
610  pTemp=(unsigned char *)malloc(imagesize);
611  pData=(unsigned char *)malloc(zbuf_size);
612  pImg1=pOut1;
613  pImg2=pOut2;
614  frames_delay = nullptr;
615 
616  /* apng decoding - begin */
617  memset(pOut1, 0, outimg1);
618  memset(pOut2, 0, outimg2);
619 
620  while (!file.eof())
621  {
622  len = read32(file);
623  chunk = read32(file);
624 
625  if (chunk == 0x504C5445) /* PLTE */
626  {
627  unsigned int col;
628  for (i=0; i<len; i++)
629  {
630  file.read((char*)&c, 1);
631  col = i/3;
632  if (col<256)
633  {
634  pal[col][i%3] = c;
635  palsize = col+1;
636  }
637  }
638  /*crc = */read32(file);
639  }
640  else if (chunk == 0x74524E53) /* tRNS */
641  {
642  hasTRNS = 1;
643  for (i=0; i<len; i++)
644  {
645  file.read((char*)&c, 1);
646  if (i<256)
647  {
648  trns[i] = c;
649  trnssize = i+1;
650  if (c == 0 && coltype == 3 && trns_idx == -1)
651  trns_idx = i;
652  }
653  }
654  if (coltype == 0)
655  {
656  trns1 = readshort(&trns[0]);
657  if (depth == 16)
658  {
659  trns[1] = trns[0]; trns[0] = 0;
660  }
661  }
662  else
663  if (coltype == 2)
664  {
665  trns1 = readshort(&trns[0]);
666  trns2 = readshort(&trns[2]);
667  trns3 = readshort(&trns[4]);
668  if (depth == 16)
669  {
670  trns[1] = trns[0]; trns[0] = 0;
671  trns[3] = trns[2]; trns[2] = 0;
672  trns[5] = trns[4]; trns[4] = 0;
673  }
674  }
675  /*crc = */read32(file);
676  }
677  else if (chunk == 0x6163544C) /* acTL */
678  {
679  frames = read32(file);
680  if(frames_delay)
681  free(frames_delay);
682  frames_delay = (unsigned short*)malloc(frames*sizeof(unsigned short));
683  loops = read32(file);
684  /*crc = */read32(file);
685  if (pOut1)
686  free(pOut1);
687  if (pOut2)
688  free(pOut2);
689  pOut1 = (unsigned char *)malloc((frames+1)*outimg1);
690  pOut2 = (unsigned char *)malloc((frames+1)*outimg2);
691  pImg1 = pOut1;
692  pImg2 = pOut2;
693  memset(pOut1, 0, outimg1);
694  memset(pOut2, 0, outimg2);
695  }
696  else if (chunk == 0x6663544C) /* fcTL */
697  {
698  if (zsize == 0)
699  first_frame = 1;
700  else
701  {
702  if (dop == PNG_DISPOSE_OP_PREVIOUS)
703  {
704  if (coltype != 6)
705  memcpy(pImg1 + outimg1, pImg1, outimg1);
706  if (coltype != 4)
707  memcpy(pImg2 + outimg2, pImg2, outimg2);
708  }
709 
710  pDst1 = pImg1 + y0*outrow1 + x0*channels;
711  pDst2 = pImg2 + y0*outrow2 + x0*4;
712  unpack(zstream, pTemp, imagesize, pData, zsize, h0, rowbytes, bpp);
713  switch (coltype)
714  {
715  case 0: compose0(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
716  case 2: compose2(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
717  case 3: compose3(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
718  case 4: compose4(pDst1, outrow1, pTemp, rowbytes+1, w0, h0, bop, depth); break;
719  case 6: compose6( pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
720  }
721  zsize = 0;
722 
723  if (dop != PNG_DISPOSE_OP_PREVIOUS)
724  {
725  if (coltype != 6)
726  memcpy(pImg1 + outimg1, pImg1, outimg1);
727  if (coltype != 4)
728  memcpy(pImg2 + outimg2, pImg2, outimg2);
729 
730  if (dop == PNG_DISPOSE_OP_BACKGROUND)
731  {
732  pDst1 += outimg1;
733  pDst2 += outimg2;
734 
735  for (j=0; j<h0; j++)
736  {
737  switch (coltype)
738  {
739  case 0: memset(pDst2, 0, w0*4); if (hasTRNS) memset(pDst1, trns[1], w0); else keep_original = 0; break;
740  case 2: memset(pDst2, 0, w0*4); if (hasTRNS) 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;
741  case 3: memset(pDst2, 0, w0*4); if (trns_idx >= 0) memset(pDst1, trns_idx, w0); else keep_original = 0; break;
742  case 4: memset(pDst1, 0, w0*2); break;
743  case 6: memset(pDst2, 0, w0*4); break;
744  }
745  pDst1 += outrow1;
746  pDst2 += outrow2;
747  }
748  }
749  }
750  }
751 
752  /*seq = */read32(file);
753  w0 = read32(file);
754  h0 = read32(file);
755  x0 = read32(file);
756  y0 = read32(file);
757  d1 = read16(file);
758  d2 = read16(file);
759  file.read((char*)&dop, 1);
760  file.read((char*)&bop, 1);
761  /*crc = */read32(file);
762 
763  if(d2 == 0)
764  d2 = 100;
765  frames_delay[cur_frame] = (d1 * 1000)/d2;
766 
767  if (cur_frame == 0)
768  {
769  bop = PNG_BLEND_OP_SOURCE;
770  if (dop == PNG_DISPOSE_OP_PREVIOUS)
772  }
773 
774  if (!(coltype & 4) && !(hasTRNS))
775  bop = PNG_BLEND_OP_SOURCE;
776 
777  rowbytes = ROWBYTES(pixeldepth, w0);
778  cur_frame++;
779  pImg1 += outimg1;
780  pImg2 += outimg2;
781  }
782  else if (chunk == 0x49444154) /* IDAT */
783  {
784  file.read((char*)(pData + zsize), len);
785  zsize += len;
786  /*crc = */read32(file);
787  }
788  else if (chunk == 0x66644154) /* fdAT */
789  {
790  /*seq = */read32(file);
791  len -= 4;
792  file.read((char*)(pData + zsize), len);
793  zsize += len;
794  /*crc = */read32(file);
795  }
796  else if (chunk == 0x49454E44) /* IEND */
797  {
798  pDst1 = pImg1 + y0*outrow1 + x0*channels;
799  pDst2 = pImg2 + y0*outrow2 + x0*4;
800  unpack(zstream, pTemp, imagesize, pData, zsize, h0, rowbytes, bpp);
801  switch (coltype)
802  {
803  case 0: compose0(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
804  case 2: compose2(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
805  case 3: compose3(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
806  case 4: compose4(pDst1, outrow1, pTemp, rowbytes+1, w0, h0, bop, depth); break;
807  case 6: compose6( pDst2, outrow2, pTemp, rowbytes+1, w0, h0, bop, depth); break;
808  }
809  break;
810  }
811  else
812  {
813  c = (unsigned char)(chunk>>24);
814  if (notabc(c)) break;
815  c = (unsigned char)((chunk>>16) & 0xFF);
816  if (notabc(c)) break;
817  c = (unsigned char)((chunk>>8) & 0xFF);
818  if (notabc(c)) break;
819  c = (unsigned char)(chunk & 0xFF);
820  if (notabc(c)) break;
821 
822  file.seekg(len, std::ios_base::cur);
823  /*crc = */read32(file);
824  }
825  }
826  /* apng decoding - end */
827 
828  if (coltype == 0)
829  {
830  switch (depth)
831  {
832  case 4: trns[1] *= 0x11; break;
833  case 2: trns[1] *= 0x55; break;
834  case 1: trns[1] *= 0xFF; break;
835  }
836  }
837 
838  inflateEnd(&zstream);
839 
840  apng->bpp = channels;
841  apng->coltype = coltype;
842  apng->last_frame = cur_frame;
843  apng->first_frame = first_frame;
844  apng->height = h;
845  apng->width = w;
846  apng->num_frames = frames;
847  apng->num_plays = loops;
848  apng->frames_delay = frames_delay;
849  apng->pdata = pOut2;
850  apng->bpp = 4;
851  apng->coltype = 6;
852 
853  if(pData)
854  free(pData);
855  if(pTemp)
856  free(pTemp);
857  if(pOut1)
858  free(pOut1);
859  } else
860  return -1;
861  } else
862  return -1;
863 
864  return 0;
865 }
866 
867 void write_chunk(std::ostream& f, const char* name, unsigned char* data, unsigned int length)
868 {
869  unsigned int crc = crc32(0, Z_NULL, 0);
870  unsigned int len = swap32(length);
871 
872  f.write((char*)&len, 4);
873  f.write(name, 4);
874  crc = crc32(crc, (const Bytef*)name, 4);
875 
876  if(data != nullptr && length > 0) {
877  f.write((char*)data, length);
878  crc = crc32(crc, data, length);
879  }
880 
881  crc = swap32(crc);
882  f.write((char*)&crc, 4);
883 }
884 
885 void write_IDATs(std::ostream& f, unsigned char* data, unsigned int length, unsigned int idat_size)
886 {
887  unsigned int z_cmf = data[0];
888 
889  if((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) {
890  if(length >= 2) {
891  unsigned int z_cinfo = z_cmf >> 4;
892  unsigned int half_z_window_size = 1 << (z_cinfo + 7);
893 
894  while(idat_size <= half_z_window_size && half_z_window_size >= 256) {
895  z_cinfo--;
896  half_z_window_size >>= 1;
897  }
898 
899  z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
900 
901  if(data[0] != (unsigned char)z_cmf) {
902  data[0] = (unsigned char)z_cmf;
903  data[1] &= 0xe0;
904  data[1] += (unsigned char)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
905  }
906  }
907  }
908 
909  while(length > 0) {
910  unsigned int ds = length;
911 
912  if(ds > PNG_ZBUF_SIZE)
913  ds = PNG_ZBUF_SIZE;
914 
915  write_chunk(f, "IDAT", data, ds);
916 
917  data += ds;
918  length -= ds;
919  }
920 }
921 
922 void save_png(std::stringstream& f, unsigned int width, unsigned int height, int channels, unsigned char *pixels)
923 {
924  unsigned int bpp = 4;
925  unsigned char coltype = 0;
926 
927  if(channels == 3)
928  coltype = 2;
929  else if (channels == 2)
930  coltype = 4;
931  else if (channels == 4)
932  coltype = 6;
933 
934  struct IHDR {
935  unsigned int mWidth;
936  unsigned int mHeight;
937  unsigned char mDepth;
938  unsigned char mColorType;
939  unsigned char mCompression;
940  unsigned char mFilterMethod;
941  unsigned char mInterlaceMethod;
942  } ihdr = { swap32(width), swap32(height), 8, coltype, 0, 0, 0 };
943 
944  z_stream zstream1;
945  z_stream zstream2;
946  unsigned int i, j;
947 
948  unsigned int rowbytes = width * bpp;
949  unsigned int idat_size = (rowbytes + 1) * height;
950  unsigned int zbuf_size = idat_size + ((idat_size + 7) >> 3) + ((idat_size + 63) >> 6) + 11;
951 
952  unsigned char* row_buf = (unsigned char*)malloc(rowbytes + 1);
953  unsigned char* sub_row = (unsigned char*)malloc(rowbytes + 1);
954  unsigned char* up_row = (unsigned char*)malloc(rowbytes + 1);
955  unsigned char* avg_row = (unsigned char*)malloc(rowbytes + 1);
956  unsigned char* paeth_row = (unsigned char*)malloc(rowbytes + 1);
957  unsigned char* zbuf1 = (unsigned char*)malloc(zbuf_size);
958  unsigned char* zbuf2 = (unsigned char*)malloc(zbuf_size);
959 
960  if(!row_buf || !sub_row || !up_row || !avg_row || !paeth_row || !zbuf1 || !zbuf2) {
961  free(row_buf);
962  free(sub_row);
963  free(up_row);
964  free(avg_row);
965  free(paeth_row);
966  free(zbuf1);
967  free(zbuf2);
968 
969  return;
970  }
971 
972  row_buf[0] = 0;
973  sub_row[0] = 1;
974  up_row[0] = 2;
975  avg_row[0] = 3;
976  paeth_row[0] = 4;
977 
978  zstream1.data_type = Z_BINARY;
979  zstream1.zalloc = Z_NULL;
980  zstream1.zfree = Z_NULL;
981  zstream1.opaque = Z_NULL;
982  deflateInit2(&zstream1, Z_BEST_COMPRESSION, 8, 15, 8, Z_DEFAULT_STRATEGY);
983 
984  zstream2.data_type = Z_BINARY;
985  zstream2.zalloc = Z_NULL;
986  zstream2.zfree = Z_NULL;
987  zstream2.opaque = Z_NULL;
988  deflateInit2(&zstream2, Z_BEST_COMPRESSION, 8, 15, 8, Z_FILTERED);
989 
990  int a, b, c, pa, pb, pc, p, v;
991  unsigned char* prev;
992  unsigned char* row;
993 
994  f.write((char*)png_sign, 8);
995  write_chunk(f, "IHDR", (unsigned char*)(&ihdr), 13);
996 
997  if(palsize > 0)
998  write_chunk(f, "PLTE", (unsigned char*)(&pal), palsize * 3);
999 
1000  if(trnssize > 0)
1001  write_chunk(f, "tRNS", trns, trnssize);
1002 
1003  zstream1.next_out = zbuf1;
1004  zstream1.avail_out = zbuf_size;
1005  zstream2.next_out = zbuf2;
1006  zstream2.avail_out = zbuf_size;
1007 
1008  prev = nullptr;
1009  row = pixels;
1010 
1011  for(j = 0; j < (unsigned int)height; j++) {
1012  unsigned char* out;
1013  unsigned int sum = 0;
1014  unsigned char* best_row = row_buf;
1015  unsigned int mins = ((unsigned int)(-1)) >> 1;
1016 
1017  out = row_buf + 1;
1018 
1019  for(i = 0; i < rowbytes; i++) {
1020  v = out[i] = row[i];
1021  sum += (v < 128) ? v : 256 - v;
1022  }
1023 
1024  mins = sum;
1025 
1026  sum = 0;
1027  out = sub_row + 1;
1028 
1029  for(i = 0; i < bpp; i++) {
1030  v = out[i] = row[i];
1031  sum += (v < 128) ? v : 256 - v;
1032  }
1033 
1034  for(i = bpp; i < rowbytes; i++) {
1035  v = out[i] = row[i] - row[i - bpp];
1036  sum += (v < 128) ? v : 256 - v;
1037 
1038  if(sum > mins) break;
1039  }
1040 
1041  if(sum < mins) {
1042  mins = sum;
1043  best_row = sub_row;
1044  }
1045 
1046  if(prev) {
1047  sum = 0;
1048  out = up_row + 1;
1049 
1050  for(i = 0; i < rowbytes; i++) {
1051  v = out[i] = row[i] - prev[i];
1052  sum += (v < 128) ? v : 256 - v;
1053 
1054  if(sum > mins) break;
1055  }
1056 
1057  if(sum < mins) {
1058  mins = sum;
1059  best_row = up_row;
1060  }
1061 
1062  sum = 0;
1063  out = avg_row + 1;
1064 
1065  for(i = 0; i < bpp; i++) {
1066  v = out[i] = row[i] - prev[i] / 2;
1067  sum += (v < 128) ? v : 256 - v;
1068  }
1069 
1070  for(i = bpp; i < rowbytes; i++) {
1071  v = out[i] = row[i] - (prev[i] + row[i - bpp]) / 2;
1072  sum += (v < 128) ? v : 256 - v;
1073 
1074  if(sum > mins) break;
1075  }
1076 
1077  if(sum < mins) {
1078  mins = sum;
1079  best_row = avg_row;
1080  }
1081 
1082  sum = 0;
1083  out = paeth_row + 1;
1084 
1085  for(i = 0; i < bpp; i++) {
1086  v = out[i] = row[i] - prev[i];
1087  sum += (v < 128) ? v : 256 - v;
1088  }
1089 
1090  for(i = bpp; i < rowbytes; i++) {
1091  a = row[i - bpp];
1092  b = prev[i];
1093  c = prev[i - bpp];
1094  p = b - c;
1095  pc = a - c;
1096  pa = abs(p);
1097  pb = abs(pc);
1098  pc = abs(p + pc);
1099  p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
1100  v = out[i] = row[i] - p;
1101  sum += (v < 128) ? v : 256 - v;
1102 
1103  if(sum > mins) break;
1104  }
1105 
1106  if(sum < mins) {
1107  best_row = paeth_row;
1108  }
1109  }
1110 
1111  zstream1.next_in = row_buf;
1112  zstream1.avail_in = rowbytes + 1;
1113  deflate(&zstream1, Z_NO_FLUSH);
1114 
1115  zstream2.next_in = best_row;
1116  zstream2.avail_in = rowbytes + 1;
1117  deflate(&zstream2, Z_NO_FLUSH);
1118 
1119  prev = row;
1120  row += rowbytes;
1121  }
1122 
1123  deflate(&zstream1, Z_FINISH);
1124  deflate(&zstream2, Z_FINISH);
1125 
1126  if(zstream1.total_out <= zstream2.total_out)
1127  write_IDATs(f, zbuf1, zstream1.total_out, idat_size);
1128  else
1129  write_IDATs(f, zbuf2, zstream2.total_out, idat_size);
1130 
1131  deflateReset(&zstream1);
1132  zstream1.data_type = Z_BINARY;
1133  deflateReset(&zstream2);
1134  zstream2.data_type = Z_BINARY;
1135 
1136  write_chunk(f, "IEND", nullptr, 0);
1137 
1138  deflateEnd(&zstream1);
1139  deflateEnd(&zstream2);
1140  free(zbuf1);
1141  free(zbuf2);
1142  free(row_buf);
1143  free(sub_row);
1144  free(up_row);
1145  free(avg_row);
1146  free(paeth_row);
1147 }
1148 
1149 void free_apng(struct apng_data *apng)
1150 {
1151  if(apng->pdata)
1152  free(apng->pdata);
1153  if(apng->frames_delay)
1154  free(apng->frames_delay);
1155 }
1156 
trns1
unsigned short trns1
Definition: apngloader.cpp:81
mask2
int mask2[4]
Definition: apngloader.cpp:70
read32
unsigned int read32(std::istream &f1)
Definition: apngloader.cpp:83
png_sign
unsigned char png_sign[8]
Definition: apngloader.cpp:65
notabc
#define notabc(c)
Definition: apngloader.cpp:58
apng_data::last_frame
unsigned int last_frame
Definition: apngloader.h:33
compose0
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)
Definition: apngloader.cpp:198
PNG_BLEND_OP_SOURCE
#define PNG_BLEND_OP_SOURCE
Definition: apngloader.cpp:55
mask1
int mask1[8]
Definition: apngloader.cpp:73
compose6
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)
Definition: apngloader.cpp:449
free_apng
void free_apng(struct apng_data *apng)
Definition: apngloader.cpp:1149
palsize
unsigned int palsize
Definition: apngloader.cpp:79
apng_data::num_plays
unsigned int num_plays
Definition: apngloader.h:37
compose2
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)
Definition: apngloader.cpp:240
apngloader.h
PNG_DISPOSE_OP_BACKGROUND
#define PNG_DISPOSE_OP_BACKGROUND
Definition: apngloader.cpp:52
ROWBYTES
#define ROWBYTES(pixel_bits, width)
Definition: apngloader.cpp:60
PNG_ZBUF_SIZE
#define PNG_ZBUF_SIZE
Definition: apngloader.cpp:49
trns2
unsigned short trns2
Definition: apngloader.cpp:81
readshort
unsigned short readshort(unsigned char *p)
Definition: apngloader.cpp:101
apng_data::height
unsigned int height
Definition: apngloader.h:31
apng_data::frames_delay
unsigned short * frames_delay
Definition: apngloader.h:38
trns3
unsigned short trns3
Definition: apngloader.cpp:81
pal
unsigned char pal[256][3]
Definition: apngloader.cpp:77
apng_data::bpp
unsigned char bpp
Definition: apngloader.h:34
read16
unsigned short read16(std::istream &f1)
Definition: apngloader.cpp:93
save_png
void save_png(std::stringstream &f, unsigned int width, unsigned int height, int channels, unsigned char *pixels)
Definition: apngloader.cpp:922
apng_data
Definition: apngloader.h:28
apng_data::first_frame
unsigned int first_frame
Definition: apngloader.h:32
mask4
int mask4[2]
Definition: apngloader.cpp:67
read_paeth_row
void read_paeth_row(unsigned char *row, unsigned char *prev_row, unsigned int rowbytes, unsigned int bpp)
Definition: apngloader.cpp:141
shift4
int shift4[2]
Definition: apngloader.cpp:68
read_average_row
void read_average_row(unsigned char *row, unsigned char *prev_row, unsigned int rowbytes, unsigned int bpp)
Definition: apngloader.cpp:123
PNG_DISPOSE_OP_PREVIOUS
#define PNG_DISPOSE_OP_PREVIOUS
Definition: apngloader.cpp:53
apng_data::num_frames
unsigned int num_frames
Definition: apngloader.h:36
compose3
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)
Definition: apngloader.cpp:312
shift1
int shift1[8]
Definition: apngloader.cpp:74
trnssize
unsigned int trnssize
Definition: apngloader.cpp:79
keep_original
unsigned int keep_original
Definition: apngloader.cpp:76
write_IDATs
void write_IDATs(std::ostream &f, unsigned char *data, unsigned int length, unsigned int idat_size)
Definition: apngloader.cpp:885
compose4
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)
Definition: apngloader.cpp:389
load_apng
int load_apng(std::stringstream &file, struct apng_data *apng)
Definition: apngloader.cpp:513
read_up_row
void read_up_row(unsigned char *row, unsigned char *prev_row, unsigned int rowbytes, unsigned int bpp)
Definition: apngloader.cpp:114
write_chunk
void write_chunk(std::ostream &f, const char *name, unsigned char *data, unsigned int length)
Definition: apngloader.cpp:867
swap32
#define swap32(data)
Definition: apngloader.cpp:46
trns
unsigned char trns[256]
Definition: apngloader.cpp:78
shift2
int shift2[4]
Definition: apngloader.cpp:71
unpack
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)
Definition: apngloader.cpp:170
apng_data::pdata
unsigned char * pdata
Definition: apngloader.h:29
hasTRNS
unsigned int hasTRNS
Definition: apngloader.cpp:80
apng_data::coltype
unsigned char coltype
Definition: apngloader.h:35
apng_data::width
unsigned int width
Definition: apngloader.h:30
read_sub_row
void read_sub_row(unsigned char *row, unsigned int rowbytes, unsigned int bpp)
Definition: apngloader.cpp:106