Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
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.2.43 [February 25, 2010]
5  * Copyright (c) 1998-2002,2004,2006-2010 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 #define PNG_INTERNAL
15 #define PNG_NO_PEDANTIC_WARNINGS
16 #include "png.h"
17 #ifdef PNG_WRITE_SUPPORTED
18 
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  &(png_ptr->row_info), /* row_info: */
37  /* png_uint_32 width; width of row */
38  /* png_uint_32 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 #ifdef PNG_WRITE_FILLER_SUPPORTED
46  if (png_ptr->transformations & PNG_FILLER)
47  png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
48  png_ptr->flags);
49 #endif
50 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
51  if (png_ptr->transformations & PNG_PACKSWAP)
52  png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
53 #endif
54 #ifdef PNG_WRITE_PACK_SUPPORTED
55  if (png_ptr->transformations & PNG_PACK)
56  png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
57  (png_uint_32)png_ptr->bit_depth);
58 #endif
59 #ifdef PNG_WRITE_SWAP_SUPPORTED
60  if (png_ptr->transformations & PNG_SWAP_BYTES)
61  png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
62 #endif
63 #ifdef PNG_WRITE_SHIFT_SUPPORTED
64  if (png_ptr->transformations & PNG_SHIFT)
65  png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
66  &(png_ptr->shift));
67 #endif
68 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
69  if (png_ptr->transformations & PNG_SWAP_ALPHA)
70  png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
71 #endif
72 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
73  if (png_ptr->transformations & PNG_INVERT_ALPHA)
74  png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
75 #endif
76 #ifdef PNG_WRITE_BGR_SUPPORTED
77  if (png_ptr->transformations & PNG_BGR)
78  png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
79 #endif
80 #ifdef PNG_WRITE_INVERT_SUPPORTED
81  if (png_ptr->transformations & PNG_INVERT_MONO)
82  png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
83 #endif
84 }
85 
86 #ifdef PNG_WRITE_PACK_SUPPORTED
87 /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
88  * row_info bit depth should be 8 (one pixel per byte). The channels
89  * should be 1 (this only happens on grayscale and paletted images).
90  */
91 void /* PRIVATE */
93 {
94  png_debug(1, "in png_do_pack");
95 
96  if (row_info->bit_depth == 8 &&
97 #ifdef PNG_USELESS_TESTS_SUPPORTED
98  row != NULL && row_info != NULL &&
99 #endif
100  row_info->channels == 1)
101  {
102  switch ((int)bit_depth)
103  {
104  case 1:
105  {
106  png_bytep sp, dp;
107  int mask, v;
108  png_uint_32 i;
109  png_uint_32 row_width = row_info->width;
110 
111  sp = row;
112  dp = row;
113  mask = 0x80;
114  v = 0;
115 
116  for (i = 0; i < row_width; i++)
117  {
118  if (*sp != 0)
119  v |= mask;
120  sp++;
121  if (mask > 1)
122  mask >>= 1;
123  else
124  {
125  mask = 0x80;
126  *dp = (png_byte)v;
127  dp++;
128  v = 0;
129  }
130  }
131  if (mask != 0x80)
132  *dp = (png_byte)v;
133  break;
134  }
135  case 2:
136  {
137  png_bytep sp, dp;
138  int shift, v;
139  png_uint_32 i;
140  png_uint_32 row_width = row_info->width;
141 
142  sp = row;
143  dp = row;
144  shift = 6;
145  v = 0;
146  for (i = 0; i < row_width; i++)
147  {
148  png_byte value;
149 
150  value = (png_byte)(*sp & 0x03);
151  v |= (value << shift);
152  if (shift == 0)
153  {
154  shift = 6;
155  *dp = (png_byte)v;
156  dp++;
157  v = 0;
158  }
159  else
160  shift -= 2;
161  sp++;
162  }
163  if (shift != 6)
164  *dp = (png_byte)v;
165  break;
166  }
167  case 4:
168  {
169  png_bytep sp, dp;
170  int shift, v;
171  png_uint_32 i;
172  png_uint_32 row_width = row_info->width;
173 
174  sp = row;
175  dp = row;
176  shift = 4;
177  v = 0;
178  for (i = 0; i < row_width; i++)
179  {
180  png_byte value;
181 
182  value = (png_byte)(*sp & 0x0f);
183  v |= (value << shift);
184 
185  if (shift == 0)
186  {
187  shift = 4;
188  *dp = (png_byte)v;
189  dp++;
190  v = 0;
191  }
192  else
193  shift -= 4;
194 
195  sp++;
196  }
197  if (shift != 4)
198  *dp = (png_byte)v;
199  break;
200  }
201  }
202  row_info->bit_depth = (png_byte)bit_depth;
203  row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
204  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
205  row_info->width);
206  }
207 }
208 #endif
209 
210 #ifdef PNG_WRITE_SHIFT_SUPPORTED
211 /* Shift pixel values to take advantage of whole range. Pass the
212  * true number of bits in bit_depth. The row should be packed
213  * according to row_info->bit_depth. Thus, if you had a row of
214  * bit depth 4, but the pixels only had values from 0 to 7, you
215  * would pass 3 as bit_depth, and this routine would translate the
216  * data to 0 to 15.
217  */
218 void /* PRIVATE */
220 {
221  png_debug(1, "in png_do_shift");
222 
223 #ifdef PNG_USELESS_TESTS_SUPPORTED
224  if (row != NULL && row_info != NULL &&
225 #else
226  if (
227 #endif
228  row_info->color_type != PNG_COLOR_TYPE_PALETTE)
229  {
230  int shift_start[4], shift_dec[4];
231  int channels = 0;
232 
233  if (row_info->color_type & PNG_COLOR_MASK_COLOR)
234  {
235  shift_start[channels] = row_info->bit_depth - bit_depth->red;
236  shift_dec[channels] = bit_depth->red;
237  channels++;
238  shift_start[channels] = row_info->bit_depth - bit_depth->green;
239  shift_dec[channels] = bit_depth->green;
240  channels++;
241  shift_start[channels] = row_info->bit_depth - bit_depth->blue;
242  shift_dec[channels] = bit_depth->blue;
243  channels++;
244  }
245  else
246  {
247  shift_start[channels] = row_info->bit_depth - bit_depth->gray;
248  shift_dec[channels] = bit_depth->gray;
249  channels++;
250  }
251  if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
252  {
253  shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
254  shift_dec[channels] = bit_depth->alpha;
255  channels++;
256  }
257 
258  /* With low row depths, could only be grayscale, so one channel */
259  if (row_info->bit_depth < 8)
260  {
261  png_bytep bp = row;
262  png_uint_32 i;
263  png_byte mask;
264  png_uint_32 row_bytes = row_info->rowbytes;
265 
266  if (bit_depth->gray == 1 && row_info->bit_depth == 2)
267  mask = 0x55;
268  else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
269  mask = 0x11;
270  else
271  mask = 0xff;
272 
273  for (i = 0; i < row_bytes; i++, bp++)
274  {
275  png_uint_16 v;
276  int j;
277 
278  v = *bp;
279  *bp = 0;
280  for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
281  {
282  if (j > 0)
283  *bp |= (png_byte)((v << j) & 0xff);
284  else
285  *bp |= (png_byte)((v >> (-j)) & mask);
286  }
287  }
288  }
289  else if (row_info->bit_depth == 8)
290  {
291  png_bytep bp = row;
292  png_uint_32 i;
293  png_uint_32 istop = channels * row_info->width;
294 
295  for (i = 0; i < istop; i++, bp++)
296  {
297 
298  png_uint_16 v;
299  int j;
300  int c = (int)(i%channels);
301 
302  v = *bp;
303  *bp = 0;
304  for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
305  {
306  if (j > 0)
307  *bp |= (png_byte)((v << j) & 0xff);
308  else
309  *bp |= (png_byte)((v >> (-j)) & 0xff);
310  }
311  }
312  }
313  else
314  {
315  png_bytep bp;
316  png_uint_32 i;
317  png_uint_32 istop = channels * row_info->width;
318 
319  for (bp = row, i = 0; i < istop; i++)
320  {
321  int c = (int)(i%channels);
323  int j;
324 
325  v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
326  value = 0;
327  for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
328  {
329  if (j > 0)
330  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
331  else
332  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
333  }
334  *bp++ = (png_byte)(value >> 8);
335  *bp++ = (png_byte)(value & 0xff);
336  }
337  }
338  }
339 }
340 #endif
341 
342 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
343 void /* PRIVATE */
345 {
346  png_debug(1, "in png_do_write_swap_alpha");
347 
348 #ifdef PNG_USELESS_TESTS_SUPPORTED
349  if (row != NULL && row_info != NULL)
350 #endif
351  {
352  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
353  {
354  /* This converts from ARGB to RGBA */
355  if (row_info->bit_depth == 8)
356  {
357  png_bytep sp, dp;
358  png_uint_32 i;
359  png_uint_32 row_width = row_info->width;
360  for (i = 0, sp = dp = row; i < row_width; i++)
361  {
362  png_byte save = *(sp++);
363  *(dp++) = *(sp++);
364  *(dp++) = *(sp++);
365  *(dp++) = *(sp++);
366  *(dp++) = save;
367  }
368  }
369  /* This converts from AARRGGBB to RRGGBBAA */
370  else
371  {
372  png_bytep sp, dp;
373  png_uint_32 i;
374  png_uint_32 row_width = row_info->width;
375 
376  for (i = 0, sp = dp = row; i < row_width; i++)
377  {
378  png_byte save[2];
379  save[0] = *(sp++);
380  save[1] = *(sp++);
381  *(dp++) = *(sp++);
382  *(dp++) = *(sp++);
383  *(dp++) = *(sp++);
384  *(dp++) = *(sp++);
385  *(dp++) = *(sp++);
386  *(dp++) = *(sp++);
387  *(dp++) = save[0];
388  *(dp++) = save[1];
389  }
390  }
391  }
392  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
393  {
394  /* This converts from AG to GA */
395  if (row_info->bit_depth == 8)
396  {
397  png_bytep sp, dp;
398  png_uint_32 i;
399  png_uint_32 row_width = row_info->width;
400 
401  for (i = 0, sp = dp = row; i < row_width; i++)
402  {
403  png_byte save = *(sp++);
404  *(dp++) = *(sp++);
405  *(dp++) = save;
406  }
407  }
408  /* This converts from AAGG to GGAA */
409  else
410  {
411  png_bytep sp, dp;
412  png_uint_32 i;
413  png_uint_32 row_width = row_info->width;
414 
415  for (i = 0, sp = dp = row; i < row_width; i++)
416  {
417  png_byte save[2];
418  save[0] = *(sp++);
419  save[1] = *(sp++);
420  *(dp++) = *(sp++);
421  *(dp++) = *(sp++);
422  *(dp++) = save[0];
423  *(dp++) = save[1];
424  }
425  }
426  }
427  }
428 }
429 #endif
430 
431 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
432 void /* PRIVATE */
434 {
435  png_debug(1, "in png_do_write_invert_alpha");
436 
437 #ifdef PNG_USELESS_TESTS_SUPPORTED
438  if (row != NULL && row_info != NULL)
439 #endif
440  {
441  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
442  {
443  /* This inverts the alpha channel in RGBA */
444  if (row_info->bit_depth == 8)
445  {
446  png_bytep sp, dp;
447  png_uint_32 i;
448  png_uint_32 row_width = row_info->width;
449  for (i = 0, sp = dp = row; i < row_width; i++)
450  {
451  /* Does nothing
452  *(dp++) = *(sp++);
453  *(dp++) = *(sp++);
454  *(dp++) = *(sp++);
455  */
456  sp+=3; dp = sp;
457  *(dp++) = (png_byte)(255 - *(sp++));
458  }
459  }
460  /* This inverts the alpha channel in RRGGBBAA */
461  else
462  {
463  png_bytep sp, dp;
464  png_uint_32 i;
465  png_uint_32 row_width = row_info->width;
466 
467  for (i = 0, sp = dp = row; i < row_width; i++)
468  {
469  /* Does nothing
470  *(dp++) = *(sp++);
471  *(dp++) = *(sp++);
472  *(dp++) = *(sp++);
473  *(dp++) = *(sp++);
474  *(dp++) = *(sp++);
475  *(dp++) = *(sp++);
476  */
477  sp+=6; dp = sp;
478  *(dp++) = (png_byte)(255 - *(sp++));
479  *(dp++) = (png_byte)(255 - *(sp++));
480  }
481  }
482  }
483  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
484  {
485  /* This inverts the alpha channel in GA */
486  if (row_info->bit_depth == 8)
487  {
488  png_bytep sp, dp;
489  png_uint_32 i;
490  png_uint_32 row_width = row_info->width;
491 
492  for (i = 0, sp = dp = row; i < row_width; i++)
493  {
494  *(dp++) = *(sp++);
495  *(dp++) = (png_byte)(255 - *(sp++));
496  }
497  }
498  /* This inverts the alpha channel in GGAA */
499  else
500  {
501  png_bytep sp, dp;
502  png_uint_32 i;
503  png_uint_32 row_width = row_info->width;
504 
505  for (i = 0, sp = dp = row; i < row_width; i++)
506  {
507  /* Does nothing
508  *(dp++) = *(sp++);
509  *(dp++) = *(sp++);
510  */
511  sp+=2; dp = sp;
512  *(dp++) = (png_byte)(255 - *(sp++));
513  *(dp++) = (png_byte)(255 - *(sp++));
514  }
515  }
516  }
517  }
518 }
519 #endif
520 
521 #ifdef PNG_MNG_FEATURES_SUPPORTED
522 /* Undoes intrapixel differencing */
523 void /* PRIVATE */
525 {
526  png_debug(1, "in png_do_write_intrapixel");
527 
528  if (
529 #ifdef PNG_USELESS_TESTS_SUPPORTED
530  row != NULL && row_info != NULL &&
531 #endif
532  (row_info->color_type & PNG_COLOR_MASK_COLOR))
533  {
534  int bytes_per_pixel;
535  png_uint_32 row_width = row_info->width;
536  if (row_info->bit_depth == 8)
537  {
538  png_bytep rp;
539  png_uint_32 i;
540 
541  if (row_info->color_type == PNG_COLOR_TYPE_RGB)
542  bytes_per_pixel = 3;
543  else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
544  bytes_per_pixel = 4;
545  else
546  return;
547 
548  for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
549  {
550  *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
551  *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
552  }
553  }
554  else if (row_info->bit_depth == 16)
555  {
556  png_bytep rp;
557  png_uint_32 i;
558 
559  if (row_info->color_type == PNG_COLOR_TYPE_RGB)
560  bytes_per_pixel = 6;
561  else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
562  bytes_per_pixel = 8;
563  else
564  return;
565 
566  for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
567  {
568  png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
569  png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
570  png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
571  png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
572  png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
573  *(rp ) = (png_byte)((red >> 8) & 0xff);
574  *(rp+1) = (png_byte)(red & 0xff);
575  *(rp+4) = (png_byte)((blue >> 8) & 0xff);
576  *(rp+5) = (png_byte)(blue & 0xff);
577  }
578  }
579  }
580 }
581 #endif /* PNG_MNG_FEATURES_SUPPORTED */
582 #endif /* PNG_WRITE_SUPPORTED */
void png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:524
void png_do_packswap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:393
void png_do_invert(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:205
png_voidp s1
Definition: png.h:1956
#define NULL
Definition: ftobjs.h:61
#define PNG_COLOR_TYPE_RGB
Definition: png.h:870
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: png.h:872
png_byte FAR * png_bytep
Definition: pngconf.h:1328
void png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
Definition: pngtrans.c:426
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:869
void png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
Definition: pngwtran.c:92
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:871
void png_do_write_transformations(png_structp png_ptr)
Definition: pngwtran.c:23
png_uint_32 i
Definition: png.h:2640
int channels
Definition: readppm.c:68
GLenum GLenum GLvoid * row
GLfloat GLfloat blue
#define png_debug(l, m)
Definition: png.h:2461
png_struct FAR * png_structp
Definition: png.h:973
GLenum GLint GLuint mask
#define PNG_COLOR_MASK_COLOR
Definition: png.h:864
const GLdouble * v
unsigned char png_byte
Definition: pngconf.h:1251
unsigned short png_uint_16
Definition: pngconf.h:1249
void png_do_bgr(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:585
const GLubyte * c
GLsizei const GLfloat * value
void png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
Definition: pngwtran.c:219
png_voidp png_voidp s2
Definition: png.h:1956
if(!abbox) return FT_THROW(Invalid_Argument)
typedef int
Definition: png.h:978
#define PNG_COLOR_MASK_ALPHA
Definition: png.h:865
void png_do_swap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:261
png_color_8 FAR * png_color_8p
Definition: png.h:455
int double red
Definition: png.h:1498
unsigned long png_uint_32
Definition: pngconf.h:1247
png_row_info FAR * png_row_infop
Definition: png.h:963
int bit_depth
Definition: readpng.c:72
void png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:344
void png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:433