Otclient 1.0  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 #pragma warning( push )
84 #pragma warning( disable : 4244)
85 unsigned int read32(std::istream& f1)
86 {
87  unsigned char a, b, c, d;
88  f1.read((char*)&a, 1);
89  f1.read((char*)&b, 1);
90  f1.read((char*)&c, 1);
91  f1.read((char*)&d, 1);
92  return (static_cast<unsigned int>(a) << 24) + (static_cast<unsigned int>(b) << 16) + (static_cast<unsigned int>(c) << 8) + static_cast<unsigned int>(d);
93 }
94 
95 unsigned short read16(std::istream& f1)
96 {
97  unsigned char a, b;
98  f1.read((char*)&a, 1);
99  f1.read((char*)&b, 1);
100  return (static_cast<unsigned short>(a) << 8) + static_cast<unsigned short>(b);
101 }
102 
103 unsigned short readshort(unsigned char* p)
104 {
105  return (static_cast<unsigned short>(*p) << 8) + static_cast<unsigned short>(*(p + 1));
106 }
107 
108 void read_sub_row(unsigned char* row, unsigned int rowbytes, unsigned int bpp)
109 {
110  unsigned int i;
111 
112  for (i = bpp; i < rowbytes; i++)
113  row[i] += row[i - bpp];
114 }
115 
116 void read_up_row(unsigned char* row, unsigned char* prev_row, unsigned int rowbytes, unsigned int)
117 {
118  unsigned int i;
119 
120  if (prev_row)
121  for (i = 0; i < rowbytes; i++)
122  row[i] += prev_row[i];
123 }
124 
125 void read_average_row(unsigned char* row, unsigned char* prev_row, unsigned int rowbytes, unsigned int bpp)
126 {
127  unsigned int i;
128 
129  if (prev_row)
130  {
131  for (i = 0; i < bpp; i++)
132  row[i] += prev_row[i] >> 1;
133  for (i = bpp; i < rowbytes; i++)
134  row[i] += (prev_row[i] + row[i - bpp]) >> 1;
135  }
136  else
137  {
138  for (i = bpp; i < rowbytes; i++)
139  row[i] += row[i - bpp] >> 1;
140  }
141 }
142 
143 void read_paeth_row(unsigned char* row, unsigned char* prev_row, unsigned int rowbytes, unsigned int bpp)
144 {
145  unsigned int i;
146  int a, b, c, pa, pb, pc, p;
147 
148  if (prev_row)
149  {
150  for (i = 0; i < bpp; i++)
151  row[i] += prev_row[i];
152  for (i = bpp; i < rowbytes; i++)
153  {
154  a = row[i - bpp];
155  b = prev_row[i];
156  c = prev_row[i - bpp];
157  p = b - c;
158  pc = a - c;
159  pa = abs(p);
160  pb = abs(pc);
161  pc = abs(p + pc);
162  row[i] += ((pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c);
163  }
164  }
165  else
166  {
167  for (i = bpp; i < rowbytes; i++)
168  row[i] += row[i - bpp];
169  }
170 }
171 
172 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)
173 {
174  unsigned int j;
175  unsigned char* row = dst;
176  unsigned char* prev_row = nullptr;
177 
178  zstream.next_out = dst;
179  zstream.avail_out = dst_size;
180  zstream.next_in = src;
181  zstream.avail_in = src_size;
182  inflate(&zstream, Z_FINISH);
183  inflateReset(&zstream);
184 
185  for (j = 0; j < h; j++)
186  {
187  switch (*row++)
188  {
189  case 0: break;
190  case 1: read_sub_row(row, rowbytes, bpp); break;
191  case 2: read_up_row(row, prev_row, rowbytes, bpp); break;
192  case 3: read_average_row(row, prev_row, rowbytes, bpp); break;
193  case 4: read_paeth_row(row, prev_row, rowbytes, bpp); break;
194  }
195  prev_row = row;
196  row += rowbytes;
197  }
198 }
199 
200 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)
201 {
202  unsigned int i, j, g, a;
203  unsigned char* sp;
204  unsigned char* dp1;
205  unsigned int* dp2;
206 
207  for (j = 0; j < h; j++)
208  {
209  sp = src + 1;
210  dp1 = dst1;
211  dp2 = (unsigned int*)dst2;
212 
213  if (bop == PNG_BLEND_OP_SOURCE)
214  {
215  switch (depth)
216  {
217  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;
218  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;
219  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;
220  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;
221  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;
222  }
223  }
224  else /* PNG_BLEND_OP_OVER */
225  {
226  switch (depth)
227  {
228  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;
229  case 8: for (i = 0; i < w; i++, dp1++, dp2++) { if (*sp != trns1) { *dp1 = *sp; *dp2 = 0xFF000000 + (*sp << 16) + (*sp << 8) + *sp; } sp++; } break;
230  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;
231  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;
232  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;
233  }
234  }
235 
236  src += srcbytes;
237  dst1 += dstbytes1;
238  dst2 += dstbytes2;
239  }
240 }
241 
242 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)
243 {
244  unsigned int i, j;
245  unsigned int r, g, b, a;
246  unsigned char* sp;
247  unsigned char* dp1;
248  unsigned int* dp2;
249 
250  for (j = 0; j < h; j++)
251  {
252  sp = src + 1;
253  dp1 = dst1;
254  dp2 = (unsigned int*)dst2;
255 
256  if (bop == PNG_BLEND_OP_SOURCE)
257  {
258  if (depth == 8)
259  {
260  for (i = 0; i < w; i++)
261  {
262  b = *sp++;
263  g = *sp++;
264  r = *sp++;
265  a = 0xFF;
266  if (hasTRNS && b == trns1 && g == trns2 && r == trns3)
267  a = 0;
268  *dp1++ = b; *dp1++ = g; *dp1++ = r;
269  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
270  }
271  }
272  else
273  {
274  for (i = 0; i < w; i++, sp += 6)
275  {
276  b = *sp;
277  g = *(sp + 2);
278  r = *(sp + 4);
279  a = 0xFF;
280  if (hasTRNS && readshort(sp) == trns1 && readshort(sp + 2) == trns2 && readshort(sp + 4) == trns3)
281  a = 0;
282  *dp1++ = b; *dp1++ = g; *dp1++ = r;
283  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
284  }
285  }
286  }
287  else /* PNG_BLEND_OP_OVER */
288  {
289  if (depth == 8)
290  {
291  for (i = 0; i < w; i++, sp += 3, dp1 += 3, dp2++)
292  if ((*sp != trns1) || (*(sp + 1) != trns2) || (*(sp + 2) != trns3))
293  {
294  *dp1 = *sp; *(dp1 + 1) = *(sp + 1); *(dp1 + 2) = *(sp + 2);
295  *dp2 = 0xFF000000 + (*(sp + 2) << 16) + (*(sp + 1) << 8) + *sp;
296  }
297  }
298  else
299  {
300  for (i = 0; i < w; i++, sp += 6, dp1 += 3, dp2++)
301  if ((readshort(sp) != trns1) || (readshort(sp + 2) != trns2) || (readshort(sp + 4) != trns3))
302  {
303  *dp1 = *sp; *(dp1 + 1) = *(sp + 2); *(dp1 + 2) = *(sp + 4);
304  *dp2 = 0xFF000000 + (*(sp + 4) << 16) + (*(sp + 2) << 8) + *sp;
305  }
306  }
307  }
308  src += srcbytes;
309  dst1 += dstbytes1;
310  dst2 += dstbytes2;
311  }
312 }
313 
314 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)
315 {
316  unsigned int i, j;
317  unsigned int r, g, b, a;
318  unsigned int r2, g2, b2, a2;
319  int u, v, al;
320  unsigned char col = 0;
321  unsigned char* sp;
322  unsigned char* dp1;
323  unsigned int* dp2;
324 
325  for (j = 0; j < h; j++)
326  {
327  sp = src + 1;
328  dp1 = dst1;
329  dp2 = (unsigned int*)dst2;
330 
331  for (i = 0; i < w; i++)
332  {
333  switch (depth)
334  {
335  case 8: col = sp[i]; break;
336  case 4: col = (sp[i >> 1] & mask4[i & 1]) >> shift4[i & 1]; break;
337  case 2: col = (sp[i >> 2] & mask2[i & 3]) >> shift2[i & 3]; break;
338  case 1: col = (sp[i >> 3] & mask1[i & 7]) >> shift1[i & 7]; break;
339  }
340 
341  b = pal[col][0];
342  g = pal[col][1];
343  r = pal[col][2];
344  a = trns[col];
345 
346  if (bop == PNG_BLEND_OP_SOURCE)
347  {
348  *dp1++ = col;
349  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
350  }
351  else /* PNG_BLEND_OP_OVER */
352  {
353  if (a == 255)
354  {
355  *dp1++ = col;
356  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
357  }
358  else
359  if (a != 0)
360  {
361  if ((a2 = (*dp2) >> 24) != 0)
362  {
363  keep_original = 0;
364  u = a * 255;
365  v = (255 - a) * a2;
366  al = 255 * 255 - (255 - a) * (255 - a2);
367  b2 = ((*dp2) & 255);
368  g2 = (((*dp2) >> 8) & 255);
369  r2 = (((*dp2) >> 16) & 255);
370  b = (b * u + b2 * v) / al;
371  g = (g * u + g2 * v) / al;
372  r = (r * u + r2 * v) / al;
373  a = al / 255;
374  }
375  *dp1++ = col;
376  *dp2++ = (a << 24) + (r << 16) + (g << 8) + b;
377  }
378  else
379  {
380  dp1++;
381  dp2++;
382  }
383  }
384  }
385  src += srcbytes;
386  dst1 += dstbytes1;
387  dst2 += dstbytes2;
388  }
389 }
390 
391 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)
392 {
393  unsigned int i, j, step;
394  unsigned int g, a, g2, a2;
395  int u, v, al;
396  unsigned char* sp;
397  unsigned char* dp;
398 
399  step = (depth + 7) / 8;
400 
401  for (j = 0; j < h; j++)
402  {
403  sp = src + 1;
404  dp = dst;
405 
406  if (bop == PNG_BLEND_OP_SOURCE)
407  {
408  for (i = 0; i < w; i++)
409  {
410  g = *sp; sp += step;
411  a = *sp; sp += step;
412  *dp++ = g;
413  *dp++ = a;
414  }
415  }
416  else /* PNG_BLEND_OP_OVER */
417  {
418  for (i = 0; i < w; i++)
419  {
420  g = *sp; sp += step;
421  a = *sp; sp += step;
422  if (a == 255)
423  {
424  *dp++ = g;
425  *dp++ = a;
426  }
427  else
428  if (a != 0)
429  {
430  if ((a2 = *(dp + 1)) != 0)
431  {
432  u = a * 255;
433  v = (255 - a) * a2;
434  al = 255 * 255 - (255 - a) * (255 - a2);
435  g2 = ((*dp) & 255);
436  g = (g * u + g2 * v) / al;
437  a = al / 255;
438  }
439  *dp++ = g;
440  *dp++ = a;
441  }
442  else
443  dp += 2;
444  }
445  }
446  src += srcbytes;
447  dst += dstbytes;
448  }
449 }
450 
451 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)
452 {
453  unsigned int i, j, step;
454  unsigned int r, g, b, a;
455  unsigned int r2, g2, b2, a2;
456  int u, v, al;
457  unsigned char* sp;
458  unsigned int* dp;
459 
460  step = (depth + 7) / 8;
461 
462  for (j = 0; j < h; j++)
463  {
464  sp = src + 1;
465  dp = (unsigned int*)dst;
466 
467  if (bop == PNG_BLEND_OP_SOURCE)
468  {
469  for (i = 0; i < w; i++)
470  {
471  b = *sp; sp += step;
472  g = *sp; sp += step;
473  r = *sp; sp += step;
474  a = *sp; sp += step;
475  *dp++ = (a << 24) + (r << 16) + (g << 8) + b;
476  }
477  }
478  else /* PNG_BLEND_OP_OVER */
479  {
480  for (i = 0; i < w; i++)
481  {
482  b = *sp; sp += step;
483  g = *sp; sp += step;
484  r = *sp; sp += step;
485  a = *sp; sp += step;
486  if (a == 255)
487  *dp++ = (a << 24) + (r << 16) + (g << 8) + b;
488  else
489  if (a != 0)
490  {
491  if ((a2 = (*dp) >> 24) != 0)
492  {
493  u = a * 255;
494  v = (255 - a) * a2;
495  al = 255 * 255 - (255 - a) * (255 - a2);
496  b2 = ((*dp) & 255);
497  g2 = (((*dp) >> 8) & 255);
498  r2 = (((*dp) >> 16) & 255);
499  b = (b * u + b2 * v) / al;
500  g = (g * u + g2 * v) / al;
501  r = (r * u + r2 * v) / al;
502  a = al / 255;
503  }
504  *dp++ = (a << 24) + (r << 16) + (g << 8) + b;
505  }
506  else
507  dp++;
508  }
509  }
510  src += srcbytes;
511  dst += dstbytes;
512  }
513 }
514 
515 int load_apng(std::stringstream& file, struct apng_data* apng)
516 {
517  unsigned int i, j;
518  unsigned int rowbytes;
519  int imagesize, zbuf_size, zsize, trns_idx;
520  unsigned int len, chunk/*, crc, seq*/;
521  unsigned int w, h, w0, h0, x0, y0;
522  unsigned int frames, loops, first_frame, cur_frame;
523  unsigned int outrow1, outrow2, outimg1, outimg2;
524  unsigned short d1, d2;
525  unsigned char c, dop = PNG_DISPOSE_OP_NONE, bop;
526  unsigned char channels, depth, pixeldepth, bpp;
527  unsigned char coltype, compr, filter, interl;
528  z_stream zstream;
529  memset(apng, 0, sizeof(struct apng_data));
530 
531  for (i = 0; i < 256; i++)
532  {
533  pal[i][0] = i;
534  pal[i][1] = i;
535  pal[i][2] = i;
536  trns[i] = 255;
537  }
538 
539  zstream.zalloc = Z_NULL;
540  zstream.zfree = Z_NULL;
541  zstream.opaque = Z_NULL;
542  inflateInit(&zstream);
543 
544  frames = 1;
545  first_frame = 0;
546  cur_frame = 0;
547  zsize = 0;
548  hasTRNS = 0;
549  trns_idx = -1;
550  x0 = 0;
551  y0 = 0;
552  loops = 0;
553  bop = PNG_BLEND_OP_SOURCE;
554 
555  unsigned char sig[8];
556  unsigned char* pOut1;
557  unsigned char* pOut2;
558  unsigned char* pTemp;
559  unsigned char* pData;
560  unsigned char* pImg1;
561  unsigned char* pImg2;
562  unsigned char* pDst1;
563  unsigned char* pDst2;
564  unsigned short* frames_delay;
565 
566  file.read((char*)sig, 8);
567  if (!file.eof() && memcmp(sig, png_sign, 8) == 0) {
568  len = read32(file);
569  chunk = read32(file);
570 
571  if ((len == 13) && (chunk == 0x49484452)) /* IHDR */
572  {
573  w = w0 = read32(file);
574  h = h0 = read32(file);
575  file.read((char*)&depth, 1);
576  file.read((char*)&coltype, 1);
577  file.read((char*)&compr, 1);
578  file.read((char*)&filter, 1);
579  file.read((char*)&interl, 1);
580  /*crc = */read32(file);
581 
582  channels = 1;
583  if (coltype == 2)
584  channels = 3;
585  else if (coltype == 4)
586  channels = 2;
587  else if (coltype == 6)
588  channels = 4;
589 
590  pixeldepth = depth * channels;
591  bpp = (pixeldepth + 7) >> 3;
592  rowbytes = ROWBYTES(pixeldepth, w);
593 
594  imagesize = (rowbytes + 1) * h;
595  zbuf_size = imagesize + ((imagesize + 7) >> 3) + ((imagesize + 63) >> 6) + 11;
596 
597  /*
598  * We'll render into 2 output buffers, first in original coltype,
599  * second in RGBA.
600  *
601  * It's better to try to keep the original coltype, but if dispose/blend
602  * operations will make it impossible, then we'll save RGBA version instead.
603  */
604 
605  outrow1 = w * channels; /* output coltype = input coltype */
606  outrow2 = w * 4; /* output coltype = RGBA */
607  outimg1 = h * outrow1;
608  outimg2 = h * outrow2;
609 
610  pOut1 = static_cast<unsigned char*>(malloc(outimg1));
611  pOut2 = static_cast<unsigned char*>(malloc(outimg2));
612  pTemp = static_cast<unsigned char*>(malloc(imagesize));
613  pData = static_cast<unsigned char*>(malloc(zbuf_size));
614  pImg1 = pOut1;
615  pImg2 = pOut2;
616  frames_delay = nullptr;
617 
618  /* apng decoding - begin */
619  memset(pOut1, 0, outimg1);
620  memset(pOut2, 0, outimg2);
621 
622  while (!file.eof())
623  {
624  len = read32(file);
625  chunk = read32(file);
626 
627  if (chunk == 0x504C5445) /* PLTE */
628  {
629  unsigned int col;
630  for (i = 0; i < len; i++)
631  {
632  file.read((char*)&c, 1);
633  col = i / 3;
634  if (col < 256)
635  {
636  pal[col][i % 3] = c;
637  palsize = col + 1;
638  }
639  }
640  /*crc = */read32(file);
641  }
642  else if (chunk == 0x74524E53) /* tRNS */
643  {
644  hasTRNS = 1;
645  for (i = 0; i < len; i++)
646  {
647  file.read((char*)&c, 1);
648  if (i < 256)
649  {
650  trns[i] = c;
651  trnssize = i + 1;
652  if (c == 0 && coltype == 3 && trns_idx == -1)
653  trns_idx = i;
654  }
655  }
656  if (coltype == 0)
657  {
658  trns1 = readshort(&trns[0]);
659  if (depth == 16)
660  {
661  trns[1] = trns[0]; trns[0] = 0;
662  }
663  }
664  else
665  if (coltype == 2)
666  {
667  trns1 = readshort(&trns[0]);
668  trns2 = readshort(&trns[2]);
669  trns3 = readshort(&trns[4]);
670  if (depth == 16)
671  {
672  trns[1] = trns[0]; trns[0] = 0;
673  trns[3] = trns[2]; trns[2] = 0;
674  trns[5] = trns[4]; trns[4] = 0;
675  }
676  }
677  /*crc = */read32(file);
678  }
679  else if (chunk == 0x6163544C) /* acTL */
680  {
681  frames = read32(file);
682  if (frames_delay)
683  free(frames_delay);
684  frames_delay = static_cast<unsigned short*>(malloc(frames * sizeof(unsigned short)));
685  loops = read32(file);
686  /*crc = */read32(file);
687  if (pOut1)
688  free(pOut1);
689  if (pOut2)
690  free(pOut2);
691  pOut1 = static_cast<unsigned char*>(malloc((frames + 1) * outimg1));
692  pOut2 = static_cast<unsigned char*>(malloc((frames + 1) * outimg2));
693  pImg1 = pOut1;
694  pImg2 = pOut2;
695  memset(pOut1, 0, outimg1);
696  memset(pOut2, 0, outimg2);
697  }
698  else if (chunk == 0x6663544C) /* fcTL */
699  {
700  if (zsize == 0)
701  first_frame = 1;
702  else
703  {
704  if (dop == PNG_DISPOSE_OP_PREVIOUS)
705  {
706  if (coltype != 6)
707  memcpy(pImg1 + outimg1, pImg1, outimg1);
708  if (coltype != 4)
709  memcpy(pImg2 + outimg2, pImg2, outimg2);
710  }
711 
712  pDst1 = pImg1 + y0 * outrow1 + x0 * channels;
713  pDst2 = pImg2 + y0 * outrow2 + x0 * 4;
714  unpack(zstream, pTemp, imagesize, pData, zsize, h0, rowbytes, bpp);
715  switch (coltype)
716  {
717  case 0: compose0(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
718  case 2: compose2(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
719  case 3: compose3(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
720  case 4: compose4(pDst1, outrow1, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
721  case 6: compose6(pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
722  }
723  zsize = 0;
724 
725  if (dop != PNG_DISPOSE_OP_PREVIOUS)
726  {
727  if (coltype != 6)
728  memcpy(pImg1 + outimg1, pImg1, outimg1);
729  if (coltype != 4)
730  memcpy(pImg2 + outimg2, pImg2, outimg2);
731 
732  if (dop == PNG_DISPOSE_OP_BACKGROUND)
733  {
734  pDst1 += outimg1;
735  pDst2 += outimg2;
736 
737  for (j = 0; j < h0; j++)
738  {
739  switch (coltype)
740  {
741  case 0: memset(pDst2, 0, w0 * 4); if (hasTRNS) memset(pDst1, trns[1], w0); else keep_original = 0; break;
742  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]; }
743  else keep_original = 0; break;
744  case 3: memset(pDst2, 0, w0 * 4); if (trns_idx >= 0) memset(pDst1, trns_idx, w0); else keep_original = 0; break;
745  case 4: memset(pDst1, 0, w0 * 2); break;
746  case 6: memset(pDst2, 0, w0 * 4); break;
747  }
748  pDst1 += outrow1;
749  pDst2 += outrow2;
750  }
751  }
752  }
753  }
754 
755  /*seq = */read32(file);
756  w0 = read32(file);
757  h0 = read32(file);
758  x0 = read32(file);
759  y0 = read32(file);
760  d1 = read16(file);
761  d2 = read16(file);
762  file.read((char*)&dop, 1);
763  file.read((char*)&bop, 1);
764  /*crc = */read32(file);
765 
766  if (d2 == 0)
767  d2 = 100;
768  frames_delay[cur_frame] = (d1 * 1000) / d2;
769 
770  if (cur_frame == 0)
771  {
772  bop = PNG_BLEND_OP_SOURCE;
773  if (dop == PNG_DISPOSE_OP_PREVIOUS)
775  }
776 
777  if (!(coltype & 4) && !(hasTRNS))
778  bop = PNG_BLEND_OP_SOURCE;
779 
780  rowbytes = ROWBYTES(pixeldepth, w0);
781  cur_frame++;
782  pImg1 += outimg1;
783  pImg2 += outimg2;
784  }
785  else if (chunk == 0x49444154) /* IDAT */
786  {
787  file.read((char*)(pData + zsize), len);
788  zsize += len;
789  /*crc = */read32(file);
790  }
791  else if (chunk == 0x66644154) /* fdAT */
792  {
793  /*seq = */read32(file);
794  len -= 4;
795  file.read((char*)(pData + zsize), len);
796  zsize += len;
797  /*crc = */read32(file);
798  }
799  else if (chunk == 0x49454E44) /* IEND */
800  {
801  pDst1 = pImg1 + y0 * outrow1 + x0 * channels;
802  pDst2 = pImg2 + y0 * outrow2 + x0 * 4;
803  unpack(zstream, pTemp, imagesize, pData, zsize, h0, rowbytes, bpp);
804  switch (coltype)
805  {
806  case 0: compose0(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
807  case 2: compose2(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
808  case 3: compose3(pDst1, outrow1, pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
809  case 4: compose4(pDst1, outrow1, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
810  case 6: compose6(pDst2, outrow2, pTemp, rowbytes + 1, w0, h0, bop, depth); break;
811  }
812  break;
813  }
814  else
815  {
816  c = static_cast<unsigned char>(chunk >> 24);
817  if (notabc(c)) break;
818  c = static_cast<unsigned char>((chunk >> 16) & 0xFF);
819  if (notabc(c)) break;
820  c = static_cast<unsigned char>((chunk >> 8) & 0xFF);
821  if (notabc(c)) break;
822  c = static_cast<unsigned char>(chunk & 0xFF);
823  if (notabc(c)) break;
824 
825  file.seekg(len, std::ios_base::cur);
826  /*crc = */read32(file);
827  }
828  }
829  /* apng decoding - end */
830 
831  if (coltype == 0)
832  {
833  switch (depth)
834  {
835  case 4: trns[1] *= 0x11; break;
836  case 2: trns[1] *= 0x55; break;
837  case 1: trns[1] *= 0xFF; break;
838  }
839  }
840 
841  inflateEnd(&zstream);
842 
843  apng->bpp = channels;
844  apng->coltype = coltype;
845  apng->last_frame = cur_frame;
846  apng->first_frame = first_frame;
847  apng->height = h;
848  apng->width = w;
849  apng->num_frames = frames;
850  apng->num_plays = loops;
851  apng->frames_delay = frames_delay;
852  apng->pdata = pOut2;
853  apng->bpp = 4;
854  apng->coltype = 6;
855 
856  if (pData)
857  free(pData);
858  if (pTemp)
859  free(pTemp);
860  if (pOut1)
861  free(pOut1);
862  }
863  else
864  return -1;
865  }
866  else
867  return -1;
868 
869  return 0;
870 }
871 
872 void write_chunk(std::ostream& f, const char* name, unsigned char* data, unsigned int length)
873 {
874  unsigned int crc = crc32(0, Z_NULL, 0);
875  unsigned int len = swap32(length);
876 
877  f.write((char*)&len, 4);
878  f.write(name, 4);
879  crc = crc32(crc, (const Bytef*)name, 4);
880 
881  if (data != nullptr && length > 0) {
882  f.write((char*)data, length);
883  crc = crc32(crc, data, length);
884  }
885 
886  crc = swap32(crc);
887  f.write((char*)&crc, 4);
888 }
889 
890 void write_IDATs(std::ostream& f, unsigned char* data, unsigned int length, unsigned int idat_size)
891 {
892  unsigned int z_cmf = data[0];
893 
894  if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) {
895  if (length >= 2) {
896  unsigned int z_cinfo = z_cmf >> 4;
897  unsigned int half_z_window_size = 1 << (z_cinfo + 7);
898 
899  while (idat_size <= half_z_window_size && half_z_window_size >= 256) {
900  z_cinfo--;
901  half_z_window_size >>= 1;
902  }
903 
904  z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
905 
906  if (data[0] != static_cast<unsigned char>(z_cmf)) {
907  data[0] = static_cast<unsigned char>(z_cmf);
908  data[1] &= 0xe0;
909  data[1] += static_cast<unsigned char>(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
910  }
911  }
912  }
913 
914  while (length > 0) {
915  unsigned int ds = length;
916 
917  if (ds > PNG_ZBUF_SIZE)
918  ds = PNG_ZBUF_SIZE;
919 
920  write_chunk(f, "IDAT", data, ds);
921 
922  data += ds;
923  length -= ds;
924  }
925 }
926 
927 void save_png(std::stringstream& f, unsigned int width, unsigned int height, int channels, unsigned char* pixels)
928 {
929  unsigned int bpp = 4;
930  unsigned char coltype = 0;
931 
932  if (channels == 3)
933  coltype = 2;
934  else if (channels == 2)
935  coltype = 4;
936  else if (channels == 4)
937  coltype = 6;
938 
939  struct IHDR {
940  unsigned int mWidth;
941  unsigned int mHeight;
942  unsigned char mDepth;
943  unsigned char mColorType;
944  unsigned char mCompression;
945  unsigned char mFilterMethod;
946  unsigned char mInterlaceMethod;
947  } ihdr = { swap32(width), swap32(height), 8, coltype, 0, 0, 0 };
948 
949  z_stream zstream1;
950  z_stream zstream2;
951  unsigned int i, j;
952 
953  unsigned int rowbytes = width * bpp;
954  unsigned int idat_size = (rowbytes + 1) * height;
955  unsigned int zbuf_size = idat_size + ((idat_size + 7) >> 3) + ((idat_size + 63) >> 6) + 11;
956 
957  unsigned char* row_buf = static_cast<unsigned char*>(malloc(rowbytes + 1));
958  unsigned char* sub_row = static_cast<unsigned char*>(malloc(rowbytes + 1));
959  unsigned char* up_row = static_cast<unsigned char*>(malloc(rowbytes + 1));
960  unsigned char* avg_row = static_cast<unsigned char*>(malloc(rowbytes + 1));
961  unsigned char* paeth_row = static_cast<unsigned char*>(malloc(rowbytes + 1));
962  unsigned char* zbuf1 = static_cast<unsigned char*>(malloc(zbuf_size));
963  unsigned char* zbuf2 = static_cast<unsigned char*>(malloc(zbuf_size));
964 
965  if (!row_buf || !sub_row || !up_row || !avg_row || !paeth_row || !zbuf1 || !zbuf2) {
966  free(row_buf);
967  free(sub_row);
968  free(up_row);
969  free(avg_row);
970  free(paeth_row);
971  free(zbuf1);
972  free(zbuf2);
973 
974  return;
975  }
976 
977  row_buf[0] = 0;
978  sub_row[0] = 1;
979  up_row[0] = 2;
980  avg_row[0] = 3;
981  paeth_row[0] = 4;
982 
983  zstream1.data_type = Z_BINARY;
984  zstream1.zalloc = Z_NULL;
985  zstream1.zfree = Z_NULL;
986  zstream1.opaque = Z_NULL;
987  deflateInit2(&zstream1, Z_BEST_COMPRESSION, 8, 15, 8, Z_DEFAULT_STRATEGY);
988 
989  zstream2.data_type = Z_BINARY;
990  zstream2.zalloc = Z_NULL;
991  zstream2.zfree = Z_NULL;
992  zstream2.opaque = Z_NULL;
993  deflateInit2(&zstream2, Z_BEST_COMPRESSION, 8, 15, 8, Z_FILTERED);
994 
995  int a, b, c, pa, pb, pc, p, v;
996  unsigned char* prev;
997  unsigned char* row;
998 
999  f.write((char*)png_sign, 8);
1000  write_chunk(f, "IHDR", (unsigned char*)(&ihdr), 13);
1001 
1002  if (palsize > 0)
1003  write_chunk(f, "PLTE", (unsigned char*)(&pal), palsize * 3);
1004 
1005  if (trnssize > 0)
1006  write_chunk(f, "tRNS", trns, trnssize);
1007 
1008  zstream1.next_out = zbuf1;
1009  zstream1.avail_out = zbuf_size;
1010  zstream2.next_out = zbuf2;
1011  zstream2.avail_out = zbuf_size;
1012 
1013  prev = nullptr;
1014  row = pixels;
1015 
1016  for (j = 0; j < static_cast<unsigned int>(height); j++) {
1017  unsigned char* out;
1018  unsigned int sum = 0;
1019  unsigned char* best_row = row_buf;
1020  unsigned int mins = static_cast<unsigned int>(-1) >> 1;
1021 
1022  out = row_buf + 1;
1023 
1024  for (i = 0; i < rowbytes; i++) {
1025  v = out[i] = row[i];
1026  sum += (v < 128) ? v : 256 - v;
1027  }
1028 
1029  mins = sum;
1030 
1031  sum = 0;
1032  out = sub_row + 1;
1033 
1034  for (i = 0; i < bpp; i++) {
1035  v = out[i] = row[i];
1036  sum += (v < 128) ? v : 256 - v;
1037  }
1038 
1039  for (i = bpp; i < rowbytes; i++) {
1040  v = out[i] = row[i] - row[i - bpp];
1041  sum += (v < 128) ? v : 256 - v;
1042 
1043  if (sum > mins) break;
1044  }
1045 
1046  if (sum < mins) {
1047  mins = sum;
1048  best_row = sub_row;
1049  }
1050 
1051  if (prev) {
1052  sum = 0;
1053  out = up_row + 1;
1054 
1055  for (i = 0; i < rowbytes; i++) {
1056  v = out[i] = row[i] - prev[i];
1057  sum += (v < 128) ? v : 256 - v;
1058 
1059  if (sum > mins) break;
1060  }
1061 
1062  if (sum < mins) {
1063  mins = sum;
1064  best_row = up_row;
1065  }
1066 
1067  sum = 0;
1068  out = avg_row + 1;
1069 
1070  for (i = 0; i < bpp; i++) {
1071  v = out[i] = row[i] - prev[i] / 2;
1072  sum += (v < 128) ? v : 256 - v;
1073  }
1074 
1075  for (i = bpp; i < rowbytes; i++) {
1076  v = out[i] = row[i] - (prev[i] + row[i - bpp]) / 2;
1077  sum += (v < 128) ? v : 256 - v;
1078 
1079  if (sum > mins) break;
1080  }
1081 
1082  if (sum < mins) {
1083  mins = sum;
1084  best_row = avg_row;
1085  }
1086 
1087  sum = 0;
1088  out = paeth_row + 1;
1089 
1090  for (i = 0; i < bpp; i++) {
1091  v = out[i] = row[i] - prev[i];
1092  sum += (v < 128) ? v : 256 - v;
1093  }
1094 
1095  for (i = bpp; i < rowbytes; i++) {
1096  a = row[i - bpp];
1097  b = prev[i];
1098  c = prev[i - bpp];
1099  p = b - c;
1100  pc = a - c;
1101  pa = abs(p);
1102  pb = abs(pc);
1103  pc = abs(p + pc);
1104  p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
1105  v = out[i] = row[i] - p;
1106  sum += (v < 128) ? v : 256 - v;
1107 
1108  if (sum > mins) break;
1109  }
1110 
1111  if (sum < mins) {
1112  best_row = paeth_row;
1113  }
1114  }
1115 
1116  zstream1.next_in = row_buf;
1117  zstream1.avail_in = rowbytes + 1;
1118  deflate(&zstream1, Z_NO_FLUSH);
1119 
1120  zstream2.next_in = best_row;
1121  zstream2.avail_in = rowbytes + 1;
1122  deflate(&zstream2, Z_NO_FLUSH);
1123 
1124  prev = row;
1125  row += rowbytes;
1126  }
1127 
1128  deflate(&zstream1, Z_FINISH);
1129  deflate(&zstream2, Z_FINISH);
1130 
1131  if (zstream1.total_out <= zstream2.total_out)
1132  write_IDATs(f, zbuf1, zstream1.total_out, idat_size);
1133  else
1134  write_IDATs(f, zbuf2, zstream2.total_out, idat_size);
1135 
1136  deflateReset(&zstream1);
1137  zstream1.data_type = Z_BINARY;
1138  deflateReset(&zstream2);
1139  zstream2.data_type = Z_BINARY;
1140 
1141  write_chunk(f, "IEND", nullptr, 0);
1142 
1143  deflateEnd(&zstream1);
1144  deflateEnd(&zstream2);
1145  free(zbuf1);
1146  free(zbuf2);
1147  free(row_buf);
1148  free(sub_row);
1149  free(up_row);
1150  free(avg_row);
1151  free(paeth_row);
1152 }
1153 
1154 void free_apng(struct apng_data* apng)
1155 {
1156  if (apng->pdata)
1157  free(apng->pdata);
1158  if (apng->frames_delay)
1159  free(apng->frames_delay);
1160 }
1161 #pragma warning( pop )
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:85
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:200
read_up_row
void read_up_row(unsigned char *row, unsigned char *prev_row, unsigned int rowbytes, unsigned int)
Definition: apngloader.cpp:116
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:451
free_apng
void free_apng(struct apng_data *apng)
Definition: apngloader.cpp:1154
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:242
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
PNG_DISPOSE_OP_NONE
#define PNG_DISPOSE_OP_NONE
Definition: apngloader.cpp:51
trns2
unsigned short trns2
Definition: apngloader.cpp:81
readshort
unsigned short readshort(unsigned char *p)
Definition: apngloader.cpp:103
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:95
save_png
void save_png(std::stringstream &f, unsigned int width, unsigned int height, int channels, unsigned char *pixels)
Definition: apngloader.cpp:927
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:143
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:125
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:314
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:890
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:391
load_apng
int load_apng(std::stringstream &file, struct apng_data *apng)
Definition: apngloader.cpp:515
write_chunk
void write_chunk(std::ostream &f, const char *name, unsigned char *data, unsigned int length)
Definition: apngloader.cpp:872
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:172
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:108