w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

pngwtran.c
Go to the documentation of this file.
1 
2 /* pngwtran.c - transforms the data in a row for PNG writers
3  *
4  * Copyright (c) 2018 Cosmin Truta
5  * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
6  * Copyright (c) 1996-1997 Andreas Dilger
7  * 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 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
18 
19 #ifdef PNG_WRITE_PACK_SUPPORTED
20 /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
21  * row_info bit depth should be 8 (one pixel per byte). The channels
22  * should be 1 (this only happens on grayscale and paletted images).
23  */
24 static void
26 {
27  png_debug(1, "in png_do_pack");
28 
29  if (row_info->bit_depth == 8 &&
30  row_info->channels == 1)
31  {
32  switch ((int)bit_depth)
33  {
34  case 1:
35  {
36  png_bytep sp, dp;
37  int mask, v;
38  png_uint_32 i;
39  png_uint_32 row_width = row_info->width;
40 
41  sp = row;
42  dp = row;
43  mask = 0x80;
44  v = 0;
45 
46  for (i = 0; i < row_width; i++)
47  {
48  if (*sp != 0)
49  v |= mask;
50 
51  sp++;
52 
53  if (mask > 1)
54  mask >>= 1;
55 
56  else
57  {
58  mask = 0x80;
59  *dp = (png_byte)v;
60  dp++;
61  v = 0;
62  }
63  }
64 
65  if (mask != 0x80)
66  *dp = (png_byte)v;
67 
68  break;
69  }
70 
71  case 2:
72  {
73  png_bytep sp, dp;
74  unsigned int shift;
75  int v;
76  png_uint_32 i;
77  png_uint_32 row_width = row_info->width;
78 
79  sp = row;
80  dp = row;
81  shift = 6;
82  v = 0;
83 
84  for (i = 0; i < row_width; i++)
85  {
87 
88  value = (png_byte)(*sp & 0x03);
89  v |= (value << shift);
90 
91  if (shift == 0)
92  {
93  shift = 6;
94  *dp = (png_byte)v;
95  dp++;
96  v = 0;
97  }
98 
99  else
100  shift -= 2;
101 
102  sp++;
103  }
104 
105  if (shift != 6)
106  *dp = (png_byte)v;
107 
108  break;
109  }
110 
111  case 4:
112  {
113  png_bytep sp, dp;
114  unsigned int shift;
115  int v;
116  png_uint_32 i;
117  png_uint_32 row_width = row_info->width;
118 
119  sp = row;
120  dp = row;
121  shift = 4;
122  v = 0;
123 
124  for (i = 0; i < row_width; i++)
125  {
126  png_byte value;
127 
128  value = (png_byte)(*sp & 0x0f);
129  v |= (value << shift);
130 
131  if (shift == 0)
132  {
133  shift = 4;
134  *dp = (png_byte)v;
135  dp++;
136  v = 0;
137  }
138 
139  else
140  shift -= 4;
141 
142  sp++;
143  }
144 
145  if (shift != 4)
146  *dp = (png_byte)v;
147 
148  break;
149  }
150 
151  default:
152  break;
153  }
154 
155  row_info->bit_depth = (png_byte)bit_depth;
156  row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
157  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
158  row_info->width);
159  }
160 }
161 #endif
162 
163 #ifdef PNG_WRITE_SHIFT_SUPPORTED
164 /* Shift pixel values to take advantage of whole range. Pass the
165  * true number of bits in bit_depth. The row should be packed
166  * according to row_info->bit_depth. Thus, if you had a row of
167  * bit depth 4, but the pixels only had values from 0 to 7, you
168  * would pass 3 as bit_depth, and this routine would translate the
169  * data to 0 to 15.
170  */
171 static void
173  png_const_color_8p bit_depth)
174 {
175  png_debug(1, "in png_do_shift");
176 
177  if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
178  {
179  int shift_start[4], shift_dec[4];
180  unsigned int channels = 0;
181 
182  if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
183  {
184  shift_start[channels] = row_info->bit_depth - bit_depth->red;
185  shift_dec[channels] = bit_depth->red;
186  channels++;
187 
188  shift_start[channels] = row_info->bit_depth - bit_depth->green;
189  shift_dec[channels] = bit_depth->green;
190  channels++;
191 
192  shift_start[channels] = row_info->bit_depth - bit_depth->blue;
193  shift_dec[channels] = bit_depth->blue;
194  channels++;
195  }
196 
197  else
198  {
199  shift_start[channels] = row_info->bit_depth - bit_depth->gray;
200  shift_dec[channels] = bit_depth->gray;
201  channels++;
202  }
203 
204  if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
205  {
206  shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
207  shift_dec[channels] = bit_depth->alpha;
208  channels++;
209  }
210 
211  /* With low row depths, could only be grayscale, so one channel */
212  if (row_info->bit_depth < 8)
213  {
214  png_bytep bp = row;
215  size_t i;
216  unsigned int mask;
217  size_t row_bytes = row_info->rowbytes;
218 
219  if (bit_depth->gray == 1 && row_info->bit_depth == 2)
220  mask = 0x55;
221 
222  else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
223  mask = 0x11;
224 
225  else
226  mask = 0xff;
227 
228  for (i = 0; i < row_bytes; i++, bp++)
229  {
230  int j;
231  unsigned int v, out;
232 
233  v = *bp;
234  out = 0;
235 
236  for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
237  {
238  if (j > 0)
239  out |= v << j;
240 
241  else
242  out |= (v >> (-j)) & mask;
243  }
244 
245  *bp = (png_byte)(out & 0xff);
246  }
247  }
248 
249  else if (row_info->bit_depth == 8)
250  {
251  png_bytep bp = row;
252  png_uint_32 i;
253  png_uint_32 istop = channels * row_info->width;
254 
255  for (i = 0; i < istop; i++, bp++)
256  {
257  unsigned int c = i%channels;
258  int j;
259  unsigned int v, out;
260 
261  v = *bp;
262  out = 0;
263 
264  for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
265  {
266  if (j > 0)
267  out |= v << j;
268 
269  else
270  out |= v >> (-j);
271  }
272 
273  *bp = (png_byte)(out & 0xff);
274  }
275  }
276 
277  else
278  {
279  png_bytep bp;
280  png_uint_32 i;
281  png_uint_32 istop = channels * row_info->width;
282 
283  for (bp = row, i = 0; i < istop; i++)
284  {
285  unsigned int c = i%channels;
286  int j;
287  unsigned int value, v;
288 
289  v = png_get_uint_16(bp);
290  value = 0;
291 
292  for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
293  {
294  if (j > 0)
295  value |= v << j;
296 
297  else
298  value |= v >> (-j);
299  }
300  *bp++ = (png_byte)((value >> 8) & 0xff);
301  *bp++ = (png_byte)(value & 0xff);
302  }
303  }
304  }
305 }
306 #endif
307 
308 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
309 static void
311 {
312  png_debug(1, "in png_do_write_swap_alpha");
313 
314  {
315  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
316  {
317  if (row_info->bit_depth == 8)
318  {
319  /* This converts from ARGB to RGBA */
320  png_bytep sp, dp;
321  png_uint_32 i;
322  png_uint_32 row_width = row_info->width;
323 
324  for (i = 0, sp = dp = row; i < row_width; i++)
325  {
326  png_byte save = *(sp++);
327  *(dp++) = *(sp++);
328  *(dp++) = *(sp++);
329  *(dp++) = *(sp++);
330  *(dp++) = save;
331  }
332  }
333 
334 #ifdef PNG_WRITE_16BIT_SUPPORTED
335  else
336  {
337  /* This converts from AARRGGBB to RRGGBBAA */
338  png_bytep sp, dp;
339  png_uint_32 i;
340  png_uint_32 row_width = row_info->width;
341 
342  for (i = 0, sp = dp = row; i < row_width; i++)
343  {
344  png_byte save[2];
345  save[0] = *(sp++);
346  save[1] = *(sp++);
347  *(dp++) = *(sp++);
348  *(dp++) = *(sp++);
349  *(dp++) = *(sp++);
350  *(dp++) = *(sp++);
351  *(dp++) = *(sp++);
352  *(dp++) = *(sp++);
353  *(dp++) = save[0];
354  *(dp++) = save[1];
355  }
356  }
357 #endif /* WRITE_16BIT */
358  }
359 
360  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
361  {
362  if (row_info->bit_depth == 8)
363  {
364  /* This converts from AG to GA */
365  png_bytep sp, dp;
366  png_uint_32 i;
367  png_uint_32 row_width = row_info->width;
368 
369  for (i = 0, sp = dp = row; i < row_width; i++)
370  {
371  png_byte save = *(sp++);
372  *(dp++) = *(sp++);
373  *(dp++) = save;
374  }
375  }
376 
377 #ifdef PNG_WRITE_16BIT_SUPPORTED
378  else
379  {
380  /* This converts from AAGG to GGAA */
381  png_bytep sp, dp;
382  png_uint_32 i;
383  png_uint_32 row_width = row_info->width;
384 
385  for (i = 0, sp = dp = row; i < row_width; i++)
386  {
387  png_byte save[2];
388  save[0] = *(sp++);
389  save[1] = *(sp++);
390  *(dp++) = *(sp++);
391  *(dp++) = *(sp++);
392  *(dp++) = save[0];
393  *(dp++) = save[1];
394  }
395  }
396 #endif /* WRITE_16BIT */
397  }
398  }
399 }
400 #endif
401 
402 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
403 static void
405 {
406  png_debug(1, "in png_do_write_invert_alpha");
407 
408  {
409  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
410  {
411  if (row_info->bit_depth == 8)
412  {
413  /* This inverts the alpha channel in RGBA */
414  png_bytep sp, dp;
415  png_uint_32 i;
416  png_uint_32 row_width = row_info->width;
417 
418  for (i = 0, sp = dp = row; i < row_width; i++)
419  {
420  /* Does nothing
421  *(dp++) = *(sp++);
422  *(dp++) = *(sp++);
423  *(dp++) = *(sp++);
424  */
425  sp+=3; dp = sp;
426  *dp = (png_byte)(255 - *(sp++));
427  }
428  }
429 
430 #ifdef PNG_WRITE_16BIT_SUPPORTED
431  else
432  {
433  /* This inverts the alpha channel in RRGGBBAA */
434  png_bytep sp, dp;
435  png_uint_32 i;
436  png_uint_32 row_width = row_info->width;
437 
438  for (i = 0, sp = dp = row; i < row_width; i++)
439  {
440  /* Does nothing
441  *(dp++) = *(sp++);
442  *(dp++) = *(sp++);
443  *(dp++) = *(sp++);
444  *(dp++) = *(sp++);
445  *(dp++) = *(sp++);
446  *(dp++) = *(sp++);
447  */
448  sp+=6; dp = sp;
449  *(dp++) = (png_byte)(255 - *(sp++));
450  *dp = (png_byte)(255 - *(sp++));
451  }
452  }
453 #endif /* WRITE_16BIT */
454  }
455 
456  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
457  {
458  if (row_info->bit_depth == 8)
459  {
460  /* This inverts the alpha channel in GA */
461  png_bytep sp, dp;
462  png_uint_32 i;
463  png_uint_32 row_width = row_info->width;
464 
465  for (i = 0, sp = dp = row; i < row_width; i++)
466  {
467  *(dp++) = *(sp++);
468  *(dp++) = (png_byte)(255 - *(sp++));
469  }
470  }
471 
472 #ifdef PNG_WRITE_16BIT_SUPPORTED
473  else
474  {
475  /* This inverts the alpha channel in GGAA */
476  png_bytep sp, dp;
477  png_uint_32 i;
478  png_uint_32 row_width = row_info->width;
479 
480  for (i = 0, sp = dp = row; i < row_width; i++)
481  {
482  /* Does nothing
483  *(dp++) = *(sp++);
484  *(dp++) = *(sp++);
485  */
486  sp+=2; dp = sp;
487  *(dp++) = (png_byte)(255 - *(sp++));
488  *dp = (png_byte)(255 - *(sp++));
489  }
490  }
491 #endif /* WRITE_16BIT */
492  }
493  }
494 }
495 #endif
496 
497 /* Transform the data according to the user's wishes. The order of
498  * transformations is significant.
499  */
500 void /* PRIVATE */
502 {
503  png_debug(1, "in png_do_write_transformations");
504 
505  if (png_ptr == NULL)
506  return;
507 
508 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
509  if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
510  if (png_ptr->write_user_transform_fn != NULL)
511  (*(png_ptr->write_user_transform_fn)) /* User write transform
512  function */
513  (png_ptr, /* png_ptr */
514  row_info, /* row_info: */
515  /* png_uint_32 width; width of row */
516  /* size_t rowbytes; number of bytes in row */
517  /* png_byte color_type; color type of pixels */
518  /* png_byte bit_depth; bit depth of samples */
519  /* png_byte channels; number of channels (1-4) */
520  /* png_byte pixel_depth; bits per pixel (depth*channels) */
521  png_ptr->row_buf + 1); /* start of pixel data for row */
522 #endif
523 
524 #ifdef PNG_WRITE_FILLER_SUPPORTED
525  if ((png_ptr->transformations & PNG_FILLER) != 0)
526  png_do_strip_channel(row_info, png_ptr->row_buf + 1,
527  !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
528 #endif
529 
530 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
531  if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
532  png_do_packswap(row_info, png_ptr->row_buf + 1);
533 #endif
534 
535 #ifdef PNG_WRITE_PACK_SUPPORTED
536  if ((png_ptr->transformations & PNG_PACK) != 0)
537  png_do_pack(row_info, png_ptr->row_buf + 1,
538  (png_uint_32)png_ptr->bit_depth);
539 #endif
540 
541 #ifdef PNG_WRITE_SWAP_SUPPORTED
542 # ifdef PNG_16BIT_SUPPORTED
543  if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
544  png_do_swap(row_info, png_ptr->row_buf + 1);
545 # endif
546 #endif
547 
548 #ifdef PNG_WRITE_SHIFT_SUPPORTED
549  if ((png_ptr->transformations & PNG_SHIFT) != 0)
550  png_do_shift(row_info, png_ptr->row_buf + 1,
551  &(png_ptr->shift));
552 #endif
553 
554 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
555  if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
556  png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
557 #endif
558 
559 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
560  if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
561  png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
562 #endif
563 
564 #ifdef PNG_WRITE_BGR_SUPPORTED
565  if ((png_ptr->transformations & PNG_BGR) != 0)
566  png_do_bgr(row_info, png_ptr->row_buf + 1);
567 #endif
568 
569 #ifdef PNG_WRITE_INVERT_SUPPORTED
570  if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
571  png_do_invert(row_info, png_ptr->row_buf + 1);
572 #endif
573 }
574 #endif /* WRITE_TRANSFORMS */
575 #endif /* WRITE */
bp
Definition: action.c:1035
int v
Definition: dviconv.c:10
#define shift
Definition: exp3.c:154
#define c(n)
Definition: gpos-common.c:150
FILE * out
Definition: hbf2gf.c:286
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
#define png_get_uint_16(buf)
Definition: png.h:2599
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:671
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: png.h:672
#define PNG_COLOR_MASK_COLOR
Definition: png.h:664
#define PNG_COLOR_MASK_ALPHA
Definition: png.h:665
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:669
unsigned int png_uint_32
Definition: pngconf.h:511
unsigned char png_byte
Definition: pngconf.h:481
png_byte * png_bytep
Definition: pngconf.h:579
#define png_debug(l, m)
Definition: pngdebug.h:145
void png_do_bgr(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:619
#define PNG_ROWBYTES(pixel_bits, width)
Definition: pngpriv.h:738
void png_do_packswap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:455
#define PNG_INVERT_ALPHA
Definition: pngpriv.h:661
#define PNG_SWAP_ALPHA
Definition: pngpriv.h:659
#define PNG_USER_TRANSFORM
Definition: pngpriv.h:662
#define PNG_SHIFT
Definition: pngpriv.h:645
void png_do_swap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:319
#define PNG_FILLER
Definition: pngpriv.h:657
#define PNG_FLAG_FILLER_AFTER
Definition: pngpriv.h:686
void png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
Definition: pngtrans.c:495
#define PNG_INVERT_MONO
Definition: pngpriv.h:647
#define PNG_PACK
Definition: pngpriv.h:644
void png_do_invert(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:262
#define PNG_PACKSWAP
Definition: pngpriv.h:658
#define PNG_SWAP_BYTES
Definition: pngpriv.h:646
#define PNG_BGR
Definition: pngpriv.h:642
void png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
Definition: pngwtran.c:501
#define png_ptr(N)
Definition: image.h:99
union value value
Definition: obx.h:44
static int row
Definition: ps2pk.c:587
#define mask(n)
Definition: lbitlib.c:93
static void png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:404
static void png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
Definition: pngwtran.c:25
static void png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
Definition: pngwtran.c:310
static void png_do_shift(png_row_infop row_info, png_bytep row, png_const_color_8p bit_depth)
Definition: pngwtran.c:172
RETTYPE mp_ptr mp_size_t mp_srcptr dp
Definition: sec_div.c:70
png_byte green
Definition: png.h:503
png_byte gray
Definition: png.h:505
png_byte blue
Definition: png.h:504
png_byte red
Definition: png.h:502
png_byte alpha
Definition: png.h:506
png_uint_32 width
Definition: png.h:756
png_byte color_type
Definition: png.h:758
png_byte bit_depth
Definition: png.h:759
png_byte pixel_depth
Definition: png.h:761
png_byte channels
Definition: png.h:760
size_t rowbytes
Definition: png.h:757
static unsigned char * save
Definition: t1disasm.c:278
int j
Definition: t4ht.c:1589
#define sp
Definition: stack.c:11
Definition: obx.h:51