zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
pngwtran.c
Go to the documentation of this file.
1 
2 /* pngwtran.c - transforms the data in a row for PNG writers
3  *
4  * Last changed in libpng 1.5.6 [November 3, 2011]
5  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8  *
9  * This code is released under the libpng license.
10  * For conditions of distribution and use, see the disclaimer
11  * and license in png.h
12  */
13 
14 #include "pngpriv.h"
15 
16 #ifdef PNG_WRITE_SUPPORTED
17 
18 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
19 /* Transform the data according to the user's wishes. The order of
20  * transformations is significant.
21  */
22 void /* PRIVATE */
24 {
25  png_debug(1, "in png_do_write_transformations");
26 
27  if (png_ptr == NULL)
28  return;
29 
30 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
31  if (png_ptr->transformations & PNG_USER_TRANSFORM)
32  if (png_ptr->write_user_transform_fn != NULL)
33  (*(png_ptr->write_user_transform_fn)) /* User write transform
34  function */
35  (png_ptr, /* png_ptr */
36  row_info, /* row_info: */
37  /* png_uint_32 width; width of row */
38  /* png_size_t rowbytes; number of bytes in row */
39  /* png_byte color_type; color type of pixels */
40  /* png_byte bit_depth; bit depth of samples */
41  /* png_byte channels; number of channels (1-4) */
42  /* png_byte pixel_depth; bits per pixel (depth*channels) */
43  png_ptr->row_buf + 1); /* start of pixel data for row */
44 #endif
45 
46 #ifdef PNG_WRITE_FILLER_SUPPORTED
47  if (png_ptr->transformations & PNG_FILLER)
48  png_do_strip_channel(row_info, png_ptr->row_buf + 1,
49  !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
50 #endif
51 
52 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
53  if (png_ptr->transformations & PNG_PACKSWAP)
54  png_do_packswap(row_info, png_ptr->row_buf + 1);
55 #endif
56 
57 #ifdef PNG_WRITE_PACK_SUPPORTED
58  if (png_ptr->transformations & PNG_PACK)
59  png_do_pack(row_info, png_ptr->row_buf + 1,
60  (png_uint_32)png_ptr->bit_depth);
61 #endif
62 
63 #ifdef PNG_WRITE_SWAP_SUPPORTED
64  if (png_ptr->transformations & PNG_SWAP_BYTES)
65  png_do_swap(row_info, png_ptr->row_buf + 1);
66 #endif
67 
68 #ifdef PNG_WRITE_SHIFT_SUPPORTED
69  if (png_ptr->transformations & PNG_SHIFT)
70  png_do_shift(row_info, png_ptr->row_buf + 1,
71  &(png_ptr->shift));
72 #endif
73 
74 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
75  if (png_ptr->transformations & PNG_SWAP_ALPHA)
76  png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
77 #endif
78 
79 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
80  if (png_ptr->transformations & PNG_INVERT_ALPHA)
81  png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
82 #endif
83 
84 #ifdef PNG_WRITE_BGR_SUPPORTED
85  if (png_ptr->transformations & PNG_BGR)
86  png_do_bgr(row_info, png_ptr->row_buf + 1);
87 #endif
88 
89 #ifdef PNG_WRITE_INVERT_SUPPORTED
90  if (png_ptr->transformations & PNG_INVERT_MONO)
91  png_do_invert(row_info, png_ptr->row_buf + 1);
92 #endif
93 }
94 
95 #ifdef PNG_WRITE_PACK_SUPPORTED
96 /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
97  * row_info bit depth should be 8 (one pixel per byte). The channels
98  * should be 1 (this only happens on grayscale and paletted images).
99  */
100 void /* PRIVATE */
102 {
103  png_debug(1, "in png_do_pack");
104 
105  if (row_info->bit_depth == 8 &&
106  row_info->channels == 1)
107  {
108  switch ((int)bit_depth)
109  {
110  case 1:
111  {
112  png_bytep sp, dp;
113  int mask, v;
114  png_uint_32 i;
115  png_uint_32 row_width = row_info->width;
116 
117  sp = row;
118  dp = row;
119  mask = 0x80;
120  v = 0;
121 
122  for (i = 0; i < row_width; i++)
123  {
124  if (*sp != 0)
125  v |= mask;
126 
127  sp++;
128 
129  if (mask > 1)
130  mask >>= 1;
131 
132  else
133  {
134  mask = 0x80;
135  *dp = (png_byte)v;
136  dp++;
137  v = 0;
138  }
139  }
140 
141  if (mask != 0x80)
142  *dp = (png_byte)v;
143 
144  break;
145  }
146 
147  case 2:
148  {
149  png_bytep sp, dp;
150  int shift, v;
151  png_uint_32 i;
152  png_uint_32 row_width = row_info->width;
153 
154  sp = row;
155  dp = row;
156  shift = 6;
157  v = 0;
158 
159  for (i = 0; i < row_width; i++)
160  {
161  png_byte value;
162 
163  value = (png_byte)(*sp & 0x03);
164  v |= (value << shift);
165 
166  if (shift == 0)
167  {
168  shift = 6;
169  *dp = (png_byte)v;
170  dp++;
171  v = 0;
172  }
173 
174  else
175  shift -= 2;
176 
177  sp++;
178  }
179 
180  if (shift != 6)
181  *dp = (png_byte)v;
182 
183  break;
184  }
185 
186  case 4:
187  {
188  png_bytep sp, dp;
189  int shift, v;
190  png_uint_32 i;
191  png_uint_32 row_width = row_info->width;
192 
193  sp = row;
194  dp = row;
195  shift = 4;
196  v = 0;
197 
198  for (i = 0; i < row_width; i++)
199  {
200  png_byte value;
201 
202  value = (png_byte)(*sp & 0x0f);
203  v |= (value << shift);
204 
205  if (shift == 0)
206  {
207  shift = 4;
208  *dp = (png_byte)v;
209  dp++;
210  v = 0;
211  }
212 
213  else
214  shift -= 4;
215 
216  sp++;
217  }
218 
219  if (shift != 4)
220  *dp = (png_byte)v;
221 
222  break;
223  }
224 
225  default:
226  break;
227  }
228 
229  row_info->bit_depth = (png_byte)bit_depth;
230  row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
231  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
232  row_info->width);
233  }
234 }
235 #endif
236 
237 #ifdef PNG_WRITE_SHIFT_SUPPORTED
238 /* Shift pixel values to take advantage of whole range. Pass the
239  * true number of bits in bit_depth. The row should be packed
240  * according to row_info->bit_depth. Thus, if you had a row of
241  * bit depth 4, but the pixels only had values from 0 to 7, you
242  * would pass 3 as bit_depth, and this routine would translate the
243  * data to 0 to 15.
244  */
245 void /* PRIVATE */
247  png_const_color_8p bit_depth)
248 {
249  png_debug(1, "in png_do_shift");
250 
251  if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
252  {
253  int shift_start[4], shift_dec[4];
254  int channels = 0;
255 
256  if (row_info->color_type & PNG_COLOR_MASK_COLOR)
257  {
258  shift_start[channels] = row_info->bit_depth - bit_depth->red;
259  shift_dec[channels] = bit_depth->red;
260  channels++;
261 
262  shift_start[channels] = row_info->bit_depth - bit_depth->green;
263  shift_dec[channels] = bit_depth->green;
264  channels++;
265 
266  shift_start[channels] = row_info->bit_depth - bit_depth->blue;
267  shift_dec[channels] = bit_depth->blue;
268  channels++;
269  }
270 
271  else
272  {
273  shift_start[channels] = row_info->bit_depth - bit_depth->gray;
274  shift_dec[channels] = bit_depth->gray;
275  channels++;
276  }
277 
278  if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
279  {
280  shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
281  shift_dec[channels] = bit_depth->alpha;
282  channels++;
283  }
284 
285  /* With low row depths, could only be grayscale, so one channel */
286  if (row_info->bit_depth < 8)
287  {
288  png_bytep bp = row;
289  png_size_t i;
290  png_byte mask;
291  png_size_t row_bytes = row_info->rowbytes;
292 
293  if (bit_depth->gray == 1 && row_info->bit_depth == 2)
294  mask = 0x55;
295 
296  else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
297  mask = 0x11;
298 
299  else
300  mask = 0xff;
301 
302  for (i = 0; i < row_bytes; i++, bp++)
303  {
304  png_uint_16 v;
305  int j;
306 
307  v = *bp;
308  *bp = 0;
309 
310  for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
311  {
312  if (j > 0)
313  *bp |= (png_byte)((v << j) & 0xff);
314 
315  else
316  *bp |= (png_byte)((v >> (-j)) & mask);
317  }
318  }
319  }
320 
321  else if (row_info->bit_depth == 8)
322  {
323  png_bytep bp = row;
324  png_uint_32 i;
325  png_uint_32 istop = channels * row_info->width;
326 
327  for (i = 0; i < istop; i++, bp++)
328  {
329 
330  png_uint_16 v;
331  int j;
332  int c = (int)(i%channels);
333 
334  v = *bp;
335  *bp = 0;
336 
337  for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
338  {
339  if (j > 0)
340  *bp |= (png_byte)((v << j) & 0xff);
341 
342  else
343  *bp |= (png_byte)((v >> (-j)) & 0xff);
344  }
345  }
346  }
347 
348  else
349  {
350  png_bytep bp;
351  png_uint_32 i;
352  png_uint_32 istop = channels * row_info->width;
353 
354  for (bp = row, i = 0; i < istop; i++)
355  {
356  int c = (int)(i%channels);
358  int j;
359 
360  v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
361  value = 0;
362 
363  for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
364  {
365  if (j > 0)
366  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
367 
368  else
369  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
370  }
371  *bp++ = (png_byte)(value >> 8);
372  *bp++ = (png_byte)(value & 0xff);
373  }
374  }
375  }
376 }
377 #endif
378 
379 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
380 void /* PRIVATE */
382 {
383  png_debug(1, "in png_do_write_swap_alpha");
384 
385  {
386  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
387  {
388  if (row_info->bit_depth == 8)
389  {
390  /* This converts from ARGB to RGBA */
391  png_bytep sp, dp;
392  png_uint_32 i;
393  png_uint_32 row_width = row_info->width;
394 
395  for (i = 0, sp = dp = row; i < row_width; i++)
396  {
397  png_byte save = *(sp++);
398  *(dp++) = *(sp++);
399  *(dp++) = *(sp++);
400  *(dp++) = *(sp++);
401  *(dp++) = save;
402  }
403  }
404 
405 #ifdef PNG_WRITE_16BIT_SUPPORTED
406  else
407  {
408  /* This converts from AARRGGBB to RRGGBBAA */
409  png_bytep sp, dp;
410  png_uint_32 i;
411  png_uint_32 row_width = row_info->width;
412 
413  for (i = 0, sp = dp = row; i < row_width; i++)
414  {
415  png_byte save[2];
416  save[0] = *(sp++);
417  save[1] = *(sp++);
418  *(dp++) = *(sp++);
419  *(dp++) = *(sp++);
420  *(dp++) = *(sp++);
421  *(dp++) = *(sp++);
422  *(dp++) = *(sp++);
423  *(dp++) = *(sp++);
424  *(dp++) = save[0];
425  *(dp++) = save[1];
426  }
427  }
428 #endif /* PNG_WRITE_16BIT_SUPPORTED */
429  }
430 
431  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
432  {
433  if (row_info->bit_depth == 8)
434  {
435  /* This converts from AG to GA */
436  png_bytep sp, dp;
437  png_uint_32 i;
438  png_uint_32 row_width = row_info->width;
439 
440  for (i = 0, sp = dp = row; i < row_width; i++)
441  {
442  png_byte save = *(sp++);
443  *(dp++) = *(sp++);
444  *(dp++) = save;
445  }
446  }
447 
448 #ifdef PNG_WRITE_16BIT_SUPPORTED
449  else
450  {
451  /* This converts from AAGG to GGAA */
452  png_bytep sp, dp;
453  png_uint_32 i;
454  png_uint_32 row_width = row_info->width;
455 
456  for (i = 0, sp = dp = row; i < row_width; i++)
457  {
458  png_byte save[2];
459  save[0] = *(sp++);
460  save[1] = *(sp++);
461  *(dp++) = *(sp++);
462  *(dp++) = *(sp++);
463  *(dp++) = save[0];
464  *(dp++) = save[1];
465  }
466  }
467 #endif /* PNG_WRITE_16BIT_SUPPORTED */
468  }
469  }
470 }
471 #endif
472 
473 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
474 void /* PRIVATE */
476 {
477  png_debug(1, "in png_do_write_invert_alpha");
478 
479  {
480  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
481  {
482  if (row_info->bit_depth == 8)
483  {
484  /* This inverts the alpha channel in RGBA */
485  png_bytep sp, dp;
486  png_uint_32 i;
487  png_uint_32 row_width = row_info->width;
488 
489  for (i = 0, sp = dp = row; i < row_width; i++)
490  {
491  /* Does nothing
492  *(dp++) = *(sp++);
493  *(dp++) = *(sp++);
494  *(dp++) = *(sp++);
495  */
496  sp+=3; dp = sp;
497  *(dp++) = (png_byte)(255 - *(sp++));
498  }
499  }
500 
501 #ifdef PNG_WRITE_16BIT_SUPPORTED
502  else
503  {
504  /* This inverts the alpha channel in RRGGBBAA */
505  png_bytep sp, dp;
506  png_uint_32 i;
507  png_uint_32 row_width = row_info->width;
508 
509  for (i = 0, sp = dp = row; i < row_width; i++)
510  {
511  /* Does nothing
512  *(dp++) = *(sp++);
513  *(dp++) = *(sp++);
514  *(dp++) = *(sp++);
515  *(dp++) = *(sp++);
516  *(dp++) = *(sp++);
517  *(dp++) = *(sp++);
518  */
519  sp+=6; dp = sp;
520  *(dp++) = (png_byte)(255 - *(sp++));
521  *(dp++) = (png_byte)(255 - *(sp++));
522  }
523  }
524 #endif /* PNG_WRITE_16BIT_SUPPORTED */
525  }
526 
527  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
528  {
529  if (row_info->bit_depth == 8)
530  {
531  /* This inverts the alpha channel in GA */
532  png_bytep sp, dp;
533  png_uint_32 i;
534  png_uint_32 row_width = row_info->width;
535 
536  for (i = 0, sp = dp = row; i < row_width; i++)
537  {
538  *(dp++) = *(sp++);
539  *(dp++) = (png_byte)(255 - *(sp++));
540  }
541  }
542 
543 #ifdef PNG_WRITE_16BIT_SUPPORTED
544  else
545  {
546  /* This inverts the alpha channel in GGAA */
547  png_bytep sp, dp;
548  png_uint_32 i;
549  png_uint_32 row_width = row_info->width;
550 
551  for (i = 0, sp = dp = row; i < row_width; i++)
552  {
553  /* Does nothing
554  *(dp++) = *(sp++);
555  *(dp++) = *(sp++);
556  */
557  sp+=2; dp = sp;
558  *(dp++) = (png_byte)(255 - *(sp++));
559  *(dp++) = (png_byte)(255 - *(sp++));
560  }
561  }
562 #endif /* PNG_WRITE_16BIT_SUPPORTED */
563  }
564  }
565 }
566 #endif
567 #endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
568 
569 #ifdef PNG_MNG_FEATURES_SUPPORTED
570 /* Undoes intrapixel differencing */
571 void /* PRIVATE */
573 {
574  png_debug(1, "in png_do_write_intrapixel");
575 
576  if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
577  {
578  int bytes_per_pixel;
579  png_uint_32 row_width = row_info->width;
580  if (row_info->bit_depth == 8)
581  {
582  png_bytep rp;
583  png_uint_32 i;
584 
585  if (row_info->color_type == PNG_COLOR_TYPE_RGB)
586  bytes_per_pixel = 3;
587 
588  else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
589  bytes_per_pixel = 4;
590 
591  else
592  return;
593 
594  for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
595  {
596  *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff);
597  *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
598  }
599  }
600 
601 #ifdef PNG_WRITE_16BIT_SUPPORTED
602  else if (row_info->bit_depth == 16)
603  {
604  png_bytep rp;
605  png_uint_32 i;
606 
607  if (row_info->color_type == PNG_COLOR_TYPE_RGB)
608  bytes_per_pixel = 6;
609 
610  else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
611  bytes_per_pixel = 8;
612 
613  else
614  return;
615 
616  for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
617  {
618  png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
619  png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
620  png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
621  png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
622  png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
623  *(rp ) = (png_byte)((red >> 8) & 0xff);
624  *(rp + 1) = (png_byte)(red & 0xff);
625  *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
626  *(rp + 5) = (png_byte)(blue & 0xff);
627  }
628  }
629 #endif /* PNG_WRITE_16BIT_SUPPORTED */
630  }
631 }
632 #endif /* PNG_MNG_FEATURES_SUPPORTED */
633 #endif /* PNG_WRITE_SUPPORTED */
void png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:572
void png_do_packswap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:396
#define PNG_BGR
Definition: pngpriv.h:431
#define PNG_INVERT_ALPHA
Definition: pngpriv.h:450
#define PNG_INVERT_MONO
Definition: pngpriv.h:436
void png_do_invert(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:210
#define NULL
Definition: ftobjs.h:61
#define PNG_SWAP_ALPHA
Definition: pngpriv.h:448
void png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
Definition: pngtrans.c:436
#define PNG_COLOR_TYPE_RGB
Definition: png.h:747
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: png.h:749
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:746
void png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
Definition: pngwtran.c:101
int32_t j
Definition: e_log.c:102
unsigned int png_uint_32
Definition: pngconf.h:441
#define png_debug(l, m)
Definition: pngdebug.h:149
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:748
PNG_CONST png_color_8 FAR * png_const_color_8p
Definition: png.h:582
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition: glew.h:11582
const GLubyte GLuint red
Definition: SDL_glfuncs.h:57
#define PNG_FILLER
Definition: pngpriv.h:446
GLenum GLenum GLvoid * row
Definition: glew.h:4447
png_struct FAR * png_structp
Definition: png.h:849
const GLdouble * v
Definition: glew.h:1377
#define PNG_COLOR_MASK_COLOR
Definition: png.h:741
int
Definition: SDL_systhread.c:37
unsigned char png_byte
Definition: pngconf.h:449
unsigned short png_uint_16
Definition: pngconf.h:447
const GLfloat * c
Definition: glew.h:14913
#define PNG_SWAP_BYTES
Definition: pngpriv.h:435
void png_do_bgr(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:546
#define PNG_PACKSWAP
Definition: pngpriv.h:447
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glew.h:11582
static double bp[]
Definition: e_pow.c:72
void png_do_shift(png_row_infop row_info, png_bytep row, png_const_color_8p bit_depth)
Definition: pngwtran.c:246
png_byte FAR * png_bytep
Definition: pngconf.h:526
EGLSurface EGLint void ** value
Definition: eglext.h:301
#define PNG_COLOR_MASK_ALPHA
Definition: png.h:742
png_row_info FAR * png_row_infop
Definition: png.h:840
void png_do_swap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:267
#define PNG_SHIFT
Definition: pngpriv.h:434
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:961
size_t png_size_t
Definition: pngconf.h:454
#define PNG_USER_TRANSFORM
Definition: pngpriv.h:451
#define PNG_FLAG_FILLER_AFTER
Definition: pngpriv.h:479
void png_do_write_transformations(png_structp png_ptr, png_row_infop row_info)
Definition: pngwtran.c:23
int i
Definition: pngrutil.c:1377
GLclampf GLclampf blue
Definition: glew.h:1506
#define PNG_ROWBYTES(pixel_bits, width)
Definition: pngpriv.h:532
#define PNG_PACK
Definition: pngpriv.h:433
void png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:381
void png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:475