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